Quand j'étais portage d'un code fortran pour c, il m'a surpris que la plupart de l'exécution de différence de temps entre le programme fortran compilé avec ifort (intel fortran compiler) et le programme c compilé avec gcc, vient d'évaluations de fonctions trigonométriques (sin
, cos
). Il m'a surpris parce que j'ai l'habitude de croire que cette réponse explique, que, comme les fonctions sinus et cosinus sont mis en œuvre dans le microcode à l'intérieur de microprocesseurs.
Afin de repérer le problème de façon plus explicite, j'ai fait un petit programme de test en 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
Sur intel Q6600
du processeur et de la 3.6.9-1-ARCH x86_64 Linux
Je reçois avec ifort version 12.1.0
$ ifort -o ftest ftest.f90
$ time ./ftest
-0.211417093282753
real 0m0.280s
user 0m0.273s
sys 0m0.003s
alors qu'avec gcc version 4.7.2
- je obtenir
$ gfortran -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m2.148s
user 0m2.090s
sys 0m0.003s
C'est près d'un facteur 10 de différence! Puis-je encore croire que la gcc de mise en œuvre de l' cos
est un wrapper autour du microprocesseur de la mise en œuvre d'une façon similaire à ce qui est probablement le cas de l'utilitaire intel de mise en œuvre? Si cela est vrai, où est le col de la bouteille?
MODIFIER
Selon les commentaires, a permis à des optimisations devraient améliorer les performances. Mon avis est que les optimisations n'affectent pas les fonctions de la bibliothèque ... ce qui ne signifie pas que je ne les utilise pas dans les programmes non triviaux. Cependant, ici, sont deux points de repère supplémentaires (maintenant sur mon ordinateur à la maison intel core2
)
$ gfortran -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m2.993s
user 0m2.986s
sys 0m0.000s
et
$ gfortran -Ofast -march=native -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m2.967s
user 0m2.960s
sys 0m0.003s
Qui particulier optimisations avez-vous (les commentateurs) ont à l'esprit? Et comment peut-compilateur exploiter un processeur multi-core dans cet exemple particulier, où chaque itération dépend du résultat de la précédente?
EDIT 2
Les tests de Daniel Fisher et Ilmari Karonen m'a fait penser que le problème pourrait être lié à la version de gcc (4.7.2) et peut-être pour un build particulière de celui-ci (Arch Linux x86_64) que j'utilise sur mes ordinateurs. J'ai donc refait le test sur l' intel core i7
boîte avec debian x86_64 Linux
, gcc version 4.4.5
et ifort version 12.1.0
$ gfortran -O3 -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m0.272s
user 0m0.268s
sys 0m0.004s
et
$ ifort -O3 -o ftest ftest.f90
$ time ./ftest
-0.211417093282753
real 0m0.178s
user 0m0.176s
sys 0m0.004s
Pour moi, c'est une très acceptable différence de performances, qui ne feraient jamais de me poser cette question. Il semble que je vais avoir à poser des questions sur Arch Linux forums sur cette question.
Cependant, l'explication de l'ensemble de l'histoire est toujours la bienvenue.