Durante il tentativo di confrontare alcune opzioni per il mio codice (usando interi a 128 bit o meno) ho osservato un comportamento che non riesco a capire. Qualcuno potrebbe far luce su questo?Ottimizzazione GCC: come rallentare le operazioni?
#include <stdio.h>
#include <stdint.h>
#include <time.h>
int main(int a, char** b)
{
printf("Running tests\n");
clock_t start = clock();
unsigned __int128 t = 13;
for(unsigned long i = 0; i < (1UL<<30); i++)
t += 23442*t + 25;
if(t == 0) printf("0\n");
printf("u128, +25, took %fs\n", double(clock() - start)/CLOCKS_PER_SEC);
start = clock();
t = 13;
for(unsigned long i = 0; i < (1UL<<30); i++)
t += 23442*t;
if(t == 0) printf("0\n");
printf("u128, no+, took %fs\n", double(clock() - start)/CLOCKS_PER_SEC);
start = clock();
unsigned long u = 13;
for(unsigned long i = 0; i < (1UL<<30); i++)
u += 23442*u + 25;
if(u == 0) printf("0\n");
printf("u64 , +25, took %fs\n", double(clock() - start)/CLOCKS_PER_SEC);
start = clock();
u = 13;
for(unsigned long i = 0; i < (1UL<<30); i++)
u += 23442*u;
if(u == 0) printf("0\n");
printf("u64 , no+, took %fs\n", double(clock() - start)/CLOCKS_PER_SEC);
return 0;
}
(Si noti che il printf sono qui in modo che gcc non ottimizza il ciclo for) Sul mio sistema, questo produce in modo affidabile il seguente output:
u128, +25, took 2.411922s
u128, no+, took 1.799805s
u64 , +25, took 1.797960s
u64 , no+, took 2.454104s
Mentre il comportamento intero a 128 bit ha senso, non riesco a vedere come il ciclo a 64 bit con meno operazioni si comporta in modo significativo (30%) più lento.
È un comportamento noto? Quale sarebbe la regola generale quando si cerca di beneficiare di questa ottimizzazione quando si scrivono loop di questo tipo?
Modifica: il comportamento viene osservato solo durante la compilazione con l'opzione -O3.
gcc -lstdc++ -O3 -o a main.cpp
u128, +25, took 2.413949s
u128, no+, took 1.799469s
u64 , +25, took 1.798278s
u64 , no+, took 2.453414s
gcc -lstdc++ -O2 -o a main.cpp
u128, +25, took 2.415244s
u128, no+, took 1.800499s
u64 , +25, took 1.798699s
u64 , no+, took 1.348133s
Fornire inoltre le impostazioni di ottimizzazione del compilatore utilizzate durante la compilazione dell'esempio. – PaulMcKenzie
Ottengo risultati simili a @ user6292850 con GCC 5.3, predefinito, con '-O', e con' -O2'. Con '-O3' anche se vedo il comportamento strano. – hvd
La risposta di magazzino: guarda il codice di assemblaggio generato e cerca di dare un senso. – PaulMcKenzie