Dichiarare le variabili dietro il ciclo o dentro il ciclo? - pagina 11

 
Vict:

Ho cercato, risulta che nessun compilatore https://en.cppreference.com/w/cpp/compiler_support ha finito i moduli, quindi non c'è niente da vedere.

È ancora possibile utilizzare i moduli tramite clang

// module
export module M;
export int f(int x) {
    return 2 + x;
}

// main.cc
import M;
int main() {
        for(int i = 0;  i < 1000000;  ++ i)
                f(5);
}

Compilato con l'ottimizzazione, il ciclo non è stato eseguito affatto (cioè l'ottimizzazione viene eseguita tra: unità di traduzione + moduli semi-connessi, invece di una sola unità di traduzione come prima). Senza alcun LTO. Il candidato std c++ passa interamente ai moduli, imho, e non ci saranno domande: "perché così lento su questo esempio artificiale con ciclo nudo".

 
Alexey Navoykov:

Quindi sembra aver capito che alloca e cancella la memoria ogni volta anche in questo caso:


A proposito, potrei aver dato risultati sbagliati l'ultima volta, molto probabilmente era in modalità x86. Ora sto testando in modalità x64 e i risultati di C++ sono molto migliori:

1) ~ 2000 msec

2) ~ 200 ms (è 3 volte più veloce).

Anche se ho anche aggiornato Studio all'ultima versione, deve aver influito anche questo dato che anche x86 è più veloce ora rispetto ai test precedenti.

Bene, ora C++ non è così vergognosamente perde contro Sharp. solo di 3 volte circa)

Hmm, quindi non c'è un garbage collector, qual è la domanda di definizione?

Non sto parlando di velocità, sto parlando di memoria
 
Alexey Navoykov , risulta che constexpr string e vector sono stati trascinati in c++20. Cioè tutti i nostri test non impiegheranno una sola istruzione per servire una stringa, ad esempio per allocare la memoria, ecc. (beh, se i simboli non provengono dai primi tempi, ovviamente). Fico.
 
Vict:
Alexey Navoykov , risulta che constexpr string e vector sono stati trascinati in C++20. Cioè tutti questi test non prenderanno una sola istruzione per il mantenimento delle stringhe, per esempio allocare la memoria, ecc. (beh, se i simboli non provengono dai primi tempi, ovviamente). Fico.

Quindi richiede di marcare tutto esplicitamente come constexpr, o lo rileverà automaticamente?

Per come la vedo io, il problema non è nello standard, ma nel compilatore. C'è qualcosa che gli impedisce di tagliare le cose inutili ora? Soprattutto è strano che il compilatore Sharp ottimizzi normalmente, mentre la versione plus della stessaMicrosoft fallisce. Anche se sembra che dovrebbero avere una base comune (in termini di ottimizzazione di tali costruzioni)

 
Alexey Navoykov:

Quindi richiede di marcare tutto esplicitamente come constexpr, o lo rileverà automaticamente?

Lo std è automatico, è sufficiente che la stringa ottenga le stringhe che sono note al momento della compilazione. Tutte le operazioni (ricerca, sostituzione, ...) con questa stringa saranno le stesse al momento della compilazione (sospetto che sharp e mcl abbiano contato anche i nostri esempi al momento della compilazione). Il piano è di rendere tutti i contenitori constepxr. Cioè non dipende più dall'umore del compilatore, ma garantito dallo standard, possiamo calcolare il parametro del template attraverso il parsing delle stringhe, per esempio. Ecco cosa è interessante - si scopre che new/delete ora è anche constexpr (per i tipi constexpr)?

Mi sembra che il problema non sia nello standard ma nel compilatore. C'è qualcosa che gli impedisce di tagliare le cose inutili? Particolarmente strano è il fatto che il compilatore Sharp ottimizza normalmente e la versione plus della stessa Microsoft fallisce, anche se sembra che debbano avere una base comune (in termini di ottimizzazione di tali costrutti)

Plus ha uno svantaggio in termini di possibilità di ottimizzazione - è solo all'interno di un'unità di traduzione (se non usiamo LTO). Naturalmente si può fare tutto lo std sui file di intestazione, ma non lo fanno (a causa del tempo di compilazione ?). Sharp con i moduli è più avanzato in questo senso. Ma c++20 risolverà presto anche questo con l'avvento dei moduli. Anche i piani per spostare std lì (prima faranno il debug dei moduli e poi lo scriveranno). Ma VS sembra aver già fatto std sui moduli, si può provare (lasciato il link sopra).

Ma insisto ancora - è meglio dichiarare dopo il ciclo (beh, se non è un tipo fondamentale).

 
Alexey Navoykov:

Ho deciso di testarlo anche in C# per curiosità. Non solo i risultati sono quasi gli stessi in velocità, ma funzionano anche molto più velocemente di C++.

Risultati:

Somma: 894782460, Tempo: 69 ms.

Somma: 894782460, Tempo: 56 ms

Ed ecco un analogo in C++:

Somma: 894782460, Tempo: 2947 ms

Somma: 894782460, Tempo: 684 ms

Lo provo in VS 2019 etutte le ottimizzazioni sono abilitate .

Al diavolo un tale C++).

p.s. I risultati in C# variano piacevolmente da test a test, ma in media entrambe le varianti sono ugualmente veloci.

Suggerimento: in sharpe string è il tipo base, in plus è una classe scritta in plus. Nella variante Sharpe l'assegnazione delle stringhe viene fatta una volta, nei plus - 10e6 volte. Alla fine, i plus sono più veloci, ma è necessario essere intelligenti quando si scrive il codice, non fare una gobba come gli indiani di Boeing.
 
SeriousRacoon:
Suggerimento: in sharpe string è il tipo base, in plus è una classe scritta in plus. Nella variante Sharpe l'assegnazione delle stringhe viene fatta una volta, nei plus - 10e6 volte. I vantaggi sono più veloci alla fine, ma è necessario accendere il cervello quando si scrive il codice invece di fare un gobbo come gli indiani in Boeing.
No, non si tratta di questo. Ho semplicemente dimenticato che la stringa esiste una classe ed è il riferimento che viene assegnato, non l'oggetto stesso. Quindi, il confronto non è corretto in questa forma
 

A proposito, parlando di ottimizzazione. Volete che il compilatore ottimizzi qualcosa qui?

mutex mtx;

void thread_0() {
        while (true) {
                do_task_0();
                {
                        lock_guard<mutex> lck{mtx};
                        do_task_1();
                }
                do_task_2();
                {
                        lock_guard<mutex> lck{mtx};
                        do_task_3();
                }
                do_task_4();
        {
}
void thread_1() {
        while (true) {
                do_task_5();
                {
                        lock_guard<mutex> lck{mtx};
                        do_task_6();
                }
                do_task_7();
                {
                        lock_guard<mutex> lck{mtx};
                        do_task_8();
                }
                do_task_9();
        {
}
 
Alexey Navoykov:
No, lì il punto è molto diverso. Ho solo dimenticato che stringa è una classe lì ed è un riferimento che viene assegnato, non l'oggetto stesso. Quindi, il confronto non è corretto in questa forma
Dove viene assegnato il riferimento (puntatore)? Nella stringa della classe plus? Cosa vuoi dire, la selezione e la copia del buffer avvengono lì.
 
SeriousRacoon:
Dove viene assegnato il riferimento (puntatore)? Nella stringa della classe plus? Cosa intendi per selezione e copia del buffer.

sta parlando di un'affilatura

Motivazione: