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.

questionAnswers(4)

yourAnswerToTheQuestion