Ogromna różnica prędkości fprintf bez „-std = c99”
Walczyłem od tygodni z tłumaczem o słabej wydajności, który napisałem. Na następującym prostym 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
}
widzimy następujący wynik
bash-3.1$ gcc -O2 -static test.c -o test
bash-3.1$ time ./test
real 0m0.334s
user 0m0.015s
sys 0m0.016s
Jak widać, w momencie dodania flagi „-std = c99” wydajność spada:
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
Kompilatorem, którego używam, jest gcc 4.6.2 mingw32.
Wygenerowany plik ma około 12M, więc jest to różnica między około 21 MB / s między tymi dwoma.
Bieganiediff
pokazuje, że wygenerowane pliki są identyczne.
Zakładałem, że ma to coś wspólnego z blokowaniem plikówfprintf
, z którego program korzysta w dużym stopniu, ale nie udało mi się znaleźć sposobu na wyłączenie go w wersji C99.
próbowałemflockfile
na strumieniu, którego używam na początku programu i odpowiadający mufunlockfile
na końcu, ale został powitany przez błędy kompilatora dotyczące niejawnych deklaracji i błędów linkera, twierdzących o niezdefiniowanych odniesieniach do tych funkcji.
Czy może istnieć inne wytłumaczenie tego problemu, a co ważniejsze, czy jest jakiś sposób na użycie C99 w systemie Windows bez płacenia tak dużej ceny?
Edytować:Po zapoznaniu się z kodem wygenerowanym przez te opcje wygląda to tak, jak w wolnych wersjach, mingw w następujący sposób:
_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
W wersji szybkiej po prostu nie istnieje; w przeciwnym razie oba są dokładnie takie same. Zakładam__mingw_vfprintf
wydaje się być tutaj slowpoke, ale nie mam pojęcia, jakie zachowanie musi emulować, co sprawia, że jest tak powolny.