Я боролся в течение нескольких недель с плохо работающим переводчиком, который я написал. На следующем простом знаке
#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
}
мы видим следующий результат:
bash-3.1$ gcc -O2 -static test.c -o test
bash-3.1$ time ./test
real 0m0.334s
user 0m0.015s
sys 0m0.016s
Как вы можете видеть, в момент добавления флага "-std = c99" производительность падает с ошибкой:
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
Я использую компилятор gcc 4.6.2 mingw32.
Сгенерированный файл составляет около 12 М, так что разница между ними составляет около 21 МБ/с.
Запуск diff
показывает, что сгенерированные файлы идентичны.
Я предположил, что это имеет какое-то отношение к блокировке файлов в fprintf
, из которых программа сильно использует, но я не смог найти способ отключить ее в версии C99.
Я попробовал flockfile
в потоке, который я использую в начале программы, и соответствующем funlockfile
в конце, но был встречен с ошибками компилятора о неявных объявлениях и ошибками компоновщика, ссылающимися на undefined ссылки на те функции.
Может быть, есть еще одно объяснение этой проблемы, и что еще более важно, есть ли способ использовать C99 для Windows, не заплатив такую огромную цену за производительность?
Изменить:
Посмотрев на код, сгенерированный этими параметрами, он выглядит как в медленных версиях, mingw придерживается следующего:
_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
В быстрой версии этого просто не существует; в противном случае оба одинаковы. Я предполагаю, что __mingw_vfprintf
кажется здесь медленным, но я не знаю, какое поведение ему нужно подражать, что делает его настолько медленным.