2017-05-09 2 views
1

All:Große Schleife wurde vom Intel Compiler ignoriert?

Ich habe einen sehr einfachen C-Test-Code mit dem Intel-Compiler einiges Timing für eine große Schleife für Schwimmer Punkt-Betrieb zu tun, wird der Code (test.c) ist wie folgt:

#include <sys/time.h> 
#include <time.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <math.h> 
#include <omp.h> 

int main(char *argc, char **argv) { 
     const long N = 1000000000; 
     double t0, t1, t2, t3; 
     double sum=0.0; 
     clock_t start, end; 
     struct timeval r_start, r_end; 
     long i; 
     gettimeofday(&r_start, NULL); 
     start = clock(); 
     for (i=0;i<N;i++) 
      sum += i*2.0+i/2.0; // doing some floating point operations 
     end = clock(); 
     gettimeofday(&r_end, NULL); 
     double cputime_elapsed_in_seconds = (end - start)/(double)CLOCKS_PER_SEC; 
     double realtime_elapsed_in_seconds = ((r_end.tv_sec * 1000000 + r_end.tv_usec) 
       - (r_start.tv_sec * 1000000 + r_start.tv_usec))/1000000.0; 
     printf("cputime_elapsed_in_sec: %e\n", cputime_elapsed_in_seconds); 
     printf("realtime_elapsed_in_sec: %e\n", realtime_elapsed_in_seconds); 
     //printf("sum= %4.3e\n", sum); 
     return 0; 
} 

jedoch als ich versuchte, es mit Intel 13,0 Compiler zu kompilieren und ausführen, die große Schleife scheint in Null Timing ignoriert und die Ausführung geführt werden:

$ icc test.c 
$ ./a.out 
cputime_elapsed_in_sec: 0.000000e+00 
realtime_elapsed_in_sec: 9.000000e-06 

Nur wenn drucke ich die Summe (uncomment Linie 26), wird die Schleife eigentlich exe sein cuted:

Die Frage ist, warum die Schleife nicht ausgeführt scheint, wenn ich den Summenwert nicht drucke?

Das gleiche Problem tritt nicht mit gcc-4.4.7 Compiler, ich denke, der Intel-Compiler möglicherweise einige Optimierung getan, dass, wenn die Variable nicht referenziert wird, wird die Schleife wahrscheinlich ignoriert?

Die Systeminformationen wie folgt dar:

$ uname -a 
Linux node001 2.6.32-642.11.1.el6.x86_64 #1 SMP Wed Oct 26 10:25:23 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux 
$ icc -v 
icc version 13.0.0 (gcc version 4.4.7 compatibility) 
$ gcc -v 
Using built-in specs. 
Target: x86_64-redhat-linux 
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux 
Thread model: posix 
gcc version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) 

Dank für Ihre Anregungen!

Roy

+0

Was ist Ihre Frage? – immibis

+0

Versuchen Sie, Optimierungen zu deaktivieren und sehen Sie, ob das Ergebnis wie beim Drucken der Summe ergibt: http://stackoverflow.com/questions/5765899/how-to-disable-compiler-optimizations-in-gcc –

+0

Eine Option ist, 'zu deklarieren Summe "als" volatil ". – paddy

Antwort

6

Angesichts Ihrer Beobachtung, dass der Endwert es verlangsamt den Druck (a), gibt es eine ziemlich gute Chance, dass der Optimierer heraus herauszufinden, dass man eigentlich nicht istsum für etwas mit nach Sie haben es berechnet und optimieren damit die gesamte Berechnungsschleife.

Ich habe vor einiger Zeit etwas Ähnliches gesehen, als wir die Leistung der neuesten VAX 11/780-Maschine, die unsere Universität erhalten hatte, getestet haben (mein Alter dort zeigend). Es war aus genau dem gleichen Grund um einen Faktor von mehreren tausend Prozent schneller, weil der neue optimierende Compiler entschieden hatte, dass die Schleife nicht wirklich benötigt wurde.

Um sicher zu sein, müssten Sie die Assembly-Ausgabe untersuchen. Ich glaube, dass dies mit icc mit der Option -Fa <asmFileName> getan werden kann und dann die Datei überprüfen, deren Name Sie anstelle von <asmFileName> verwendet haben.


(a) Die andere Möglichkeit dachte ich an scheint hier zu diskontieren.

Das war die Möglichkeit, dass der Bereich i konstant ist (basierend auf N) und dass die Berechnung sonst Konstanten enthält, könnte es sein, dass der Compiler selbst den endgültigen Wert beim Kompilieren berechnet hat, was zu einem einfachen Ergebnis führt Dauerlastbetrieb.

Ich habe gesehen, gcc machen diese Art von Sache bei seiner -O3 "wahnsinnig" -Optimierungsstufe.

Ich rate diese Möglichkeit ab, da das Drucken des Wertes höchstwahrscheinlich diesen Vorgang nicht beeinflussen würde.

+0

Vielen Dank für die Antwort, ich habe versucht -O1, -O2, -O3 ohne die Drucksumme Zeile, das gleiche Ergebnis. Wenn die Optimierung mit -O0 komplett abgeschaltet wird, wurde die Schleife ausgeführt, also denke ich, die Antwort sollte sein, dass der Compiler die gesamte Schleife optimiert hat. –

Verwandte Themen