Gran diferencia de velocidad de fprintf sin "-std = c99"
Había estado luchando durante semanas con un traductor de bajo rendimiento que había escrito. En el siguiente bechmark simple
#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
}
vemos el siguiente resultado
bash-3.1$ gcc -O2 -static test.c -o test
bash-3.1$ time ./test
real 0m0.334s
user 0m0.015s
sys 0m0.016s
Como puede ver, en el momento en que se agrega el indicador "-std = c99", el rendimiento se derrumba:
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
El compilador que estoy usando es gcc 4.6.2 mingw32.
El archivo generado es de aproximadamente 12M, por lo que esta es una diferencia de aproximadamente 21MB / s entre los dos.
Corriendodiff
Muestra que los archivos generados son idénticos.
Asumí que esto tiene algo que ver con el bloqueo de archivosfprintf
, del cual el programa hace un uso intensivo, pero no he podido encontrar una manera de apagarlo en la versión C99.
Lo intentéflockfile
en el flujo que utilizo al principio del programa, y un correspondientefunlockfile
al final, pero fue recibido con errores de compilación sobre declaraciones implícitas y errores de vinculador que afirman referencias indefinidas a esas funciones.
¿Podría haber otra explicación para este problema y, lo que es más importante, hay alguna forma de usar C99 en Windows sin pagar un precio tan alto por el rendimiento?
Editar:Después de ver el código generado por estas opciones, parece que en las versiones lentas, mingw se pega en lo siguiente:
_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
En la versión rápida, esto simplemente no existe; De lo contrario, ambos son exactamente iguales. Asumo__mingw_vfprintf
Parece ser el lenguaje lento aquí, pero no tengo idea de qué comportamiento debe emular, lo que lo hace tan lento.