Когда я переносил некоторый код fortran на c, он удивил меня тем, что большая часть несоответствия времени выполнения между программой fortran, скомпилированной с ifort (intel fortran compiler) и c-программой, скомпилированной с gcc, исходит из оценок тригонометрических функции (sin
, cos
). Это меня удивило, потому что я верил в то, что объясняет этот , что функции, такие как синус и косинус, реализованы в микрокоде внутри микропроцессоров.
Чтобы выявить проблему более явно, я сделал небольшую тестовую программу в fortran
program ftest
implicit none
real(8) :: x
integer :: i
x = 0d0
do i = 1, 10000000
x = cos (2d0 * x)
end do
write (*,*) x
end program ftest
В процессоре intel Q6600
и 3.6.9-1-ARCH x86_64 Linux
Я получаю с ifort version 12.1.0
$ ifort -o ftest ftest.f90
$ time ./ftest
-0.211417093282753
real 0m0.280s
user 0m0.273s
sys 0m0.003s
а при gcc version 4.7.2
я получаю
$ gfortran -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m2.148s
user 0m2.090s
sys 0m0.003s
Это почти различие в 10 раз! Могу ли я по-прежнему полагать, что реализация gcc cos
является оболочкой реализации микропроцессора так же, как это, вероятно, сделано в реализации Intel? Если это правда, где находится горло бутылки?
ИЗМЕНИТЬ
Согласно комментариям, включенные оптимизации должны повысить производительность. Мое мнение заключалось в том, что оптимизация не влияет на функции библиотеки... что не означает, что я не использую их в нетривиальных программах. Однако, вот два дополнительных теста (теперь на моем домашнем компьютере intel core2
)
$ gfortran -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m2.993s
user 0m2.986s
sys 0m0.000s
и
$ gfortran -Ofast -march=native -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m2.967s
user 0m2.960s
sys 0m0.003s
Какие конкретные оптимизации вы имели в виду (комментаторы)? И как компилятор может использовать многоядерный процессор в этом конкретном примере, где каждая итерация зависит от результата предыдущего?
РЕДАКТИРОВАТЬ 2
Базовые тесты Даниэля Фишера и Илмари Каронена заставили меня подумать, что проблема может быть связана с конкретной версией gcc (4.7.2) и, возможно, с конкретной сборкой (Arch x86_64 Linux), которую я использую мои компьютеры. Поэтому я повторил тест в поле intel core i7
с debian x86_64 Linux
, gcc version 4.4.5
и ifort version 12.1.0
$ gfortran -O3 -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m0.272s
user 0m0.268s
sys 0m0.004s
и
$ ifort -O3 -o ftest ftest.f90
$ time ./ftest
-0.211417093282753
real 0m0.178s
user 0m0.176s
sys 0m0.004s
Для меня это очень приемлемая разница в производительности, которая никогда не заставит меня задавать этот вопрос. Кажется, что я должен буду спросить на форумах Arch Linux об этой проблеме.
Однако объяснение всей истории по-прежнему очень приветствуется.