Massiver fprintf Geschwindigkeitsunterschied ohne "-std = c99"
Ich hatte wochenlang Probleme mit einem leistungsschwachen Übersetzer, den ich geschrieben hatte. Auf dem folgenden einfachen bechmark
#include<stdio.h>
int main()
{
int x;
char buf[2048];
FILE *test = fopen("test.out", "wb");
setvbuf(test, buf, _IOFBF, sizeof buf);
for(x=0;x<1024*1024; x++)
fprintf(test, "%04d", x);
fclose(test);
return 0
}
Wir sehen das folgende Ergebnis
bash-3.1$ gcc -O2 -static test.c -o test
bash-3.1$ time ./test
real 0m0.334s
user 0m0.015s
sys 0m0.016s
Wie Sie sehen, stürzt die Leistung ab, sobald das Flag "-std = c99" hinzugefügt wird:
bash-3.1$ gcc -O2 -static -std=c99 test.c -o test
bash-3.1$ time ./test
real 0m2.477s
user 0m0.015s
sys 0m0.000s
Der von mir verwendete Compiler ist gcc 4.6.2 mingw32.
Die erzeugte Datei hat eine Größe von ca. 12 MB, dies ist also ein Unterschied zwischen den beiden Größen von ca. 21 MB / s.
Laufendiff
Zeigt an, dass die generierten Dateien identisch sind.
Ich nahm an, dass dies etwas mit dem Sperren von Dateien zu tun hatfprintf
, von dem das Programm viel Gebrauch macht, aber ich habe in der C99-Version keinen Weg gefunden, das auszuschalten.
Ich habe es versuchtflockfile
auf dem stream verwende ich am anfang des programms auch ein entsprechendesfunlockfile
am Ende wurde aber mit Compiler-Fehlern über implizite Deklarationen und Linker-Fehlern begrüßt, die undefinierte Verweise auf diese Funktionen beanspruchen.
Könnte es eine andere Erklärung für dieses Problem geben, und was noch wichtiger ist, gibt es eine Möglichkeit, C99 unter Windows zu verwenden, ohne einen so enormen Leistungspreis zu zahlen?
Bearbeiten:Nachdem Sie sich den Code angesehen haben, der mit diesen Optionen generiert wurde, sieht es in den langsamen Versionen so aus, als ob mingw Folgendes festhält:
_fprintf:
LFB0:
.cfi_startproc
subl $28, %esp
.cfi_def_cfa_offset 32
leal 40(%esp), %eax
movl %eax, 8(%esp)
movl 36(%esp), %eax
movl %eax, 4(%esp)
movl 32(%esp), %eax
movl %eax, (%esp)
call ___mingw_vfprintf
addl $28, %esp
.cfi_def_cfa_offset 4
ret
.cfi_endproc
In der schnellen Version existiert dies einfach nicht; Ansonsten sind beide genau gleich. ich nehme an__mingw_vfprintf
scheint der Slowpoke hier zu sein, aber ich habe keine Ahnung, welches Verhalten es emulieren muss, das es so langsam macht.