I tentativi di ottimizzare il loop utilizzando un costrutto (incluso il taglio manuale di & che incolla il codice) per ottimizzare la velocità di esecuzione del loop sono sconsigliati. Non farlo; probabilmente "annullerebbe" la velocità di esecuzione.
In qualsiasi implementazione C++ che abbia mai incontrato (MSVC 6.0, 2003, 2005, 2010, GCC varie versioni, Diab varie versioni), c'è assolutamente zero, mi dispiace non averlo sottolineato abbastanza, ZERO, tempo richiesto con l'allocazione di una variabile di conteggio del ciclo, supponendo che siano state allocate altre variabili per la funzione in cui è allocata la variabile di conteggio del ciclo. Per un ciclo semplice che non fa chiamate di funzioni, la variabile di conteggio del ciclo potrebbe non essere mai nemmeno uscita in memoria; può essere tenuto interamente in un unico registro CPU per tutta la sua durata. Anche se è immagazzinato in memoria, sarebbe sullo stack di runtime, e lo spazio per esso (e qualsiasi altra variabile locale) verrebbe rivendicato tutto in una volta in un'unica operazione, che non richiede più o meno tempo a seconda del numero di variabili allocate nello stack. Le variabili locali come la variabile del ciclo di loop sono allocate nello stack e le allocazioni di stack sono ECONOMICHE A BUON MERCATO ECONOMICO, a differenza delle allocazioni di heap.
allocazione
Esempio contatore di ciclo variabile in pila:
for (int i=0; i<50; ++i) {
....
}
altro esempio circuito contatore allocazione variabile in pila:
int i = 0;
for (; i<50; ++i) {
....
}
variabile Esempio contatore di ciclo assegnato in mucchio (non fare questo: è stupido):
int* ip = new int;
for (*ip=0; *ip<50; ++(*ip)) {
....
}
delete ip;
Ora per affrontare il problema di atte per ottimizzare il ciclo copiando manualmente la copia & invece di utilizzare un contatore &:
Quello che stai pensando di fare è una forma manuale di srotolamento del ciclo. Lo srotolamento del ciclo è un'ottimizzazione che i compilatori utilizzano a volte per ridurre l'overhead coinvolto in un ciclo. I compilatori possono farlo solo se il numero di iterazioni del ciclo può essere conosciuto in fase di compilazione (cioè il numero di iterazioni è una costante, anche se la costante implica il calcolo basato su altre costanti). In alcuni casi, il compilatore può determinare che vale la pena di srotolare il ciclo, ma spesso non lo srotolerà completamente. Ad esempio, nel tuo esempio, il compilatore può determinare che sarebbe un vantaggio di velocità srotolare il ciclo da 50 iterazioni a solo 10 iterazioni con 5 copie del corpo del ciclo. La variabile del ciclo sarebbe ancora lì, ma invece di fare 50 confronti del contatore del ciclo, ora il codice deve fare il confronto solo 10 volte. È un compromesso, perché le 5 copie del corpo del ciclo consumano 5 volte più spazio nella cache, il che significa che il caricamento di quelle copie aggiuntive delle stesse istruzioni costringe la cache a sfrattare (buttare via) molte istruzioni che sono già in la cache e che potresti voler rimanere nella cache. Inoltre, il caricamento di quelle 4 copie extra delle istruzioni del corpo del loop dalla memoria principale richiede molto, molto più tempo del semplice prelievo delle istruzioni già caricate dalla cache nel caso in cui il loop non sia srotolato affatto.
Quindi, tutto sommato, è spesso più vantaggioso utilizzare solo una copia del corpo del loop e andare avanti e lasciare la logica del loop in posizione. (Ad esempio, non eseguire alcun ciclo di srotolamento.)
Stai cercando solo una ripetizione? come in 50 esecuzioni del codice sans- * any * conditionals? – WhozCraig
Per quanto ne so, il compilatore spesso ottimizza un ciclo for utilizzando una dimensione letterale (non basata su variabili) nello stesso codice risultante di aver scritto quel codice x volte. Quindi 'repeat (50)' sarebbe uguale a 'for (char i = 0; i <50; i ++)' (ho usato char causa nel caso in cui non sia ottimizzato out non assegnerà 4 byte per il 'int' ma solo 1 per il 'char'). –
@MrUniverse Grande, grazie, proprio quello di cui avevo bisogno. – Serdnad