30 votes

Pourquoi la bibliothèque mathématique gcc est-elle si inefficace?

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.

16voto

janneb Points 17303

La plupart de cela est dû à des différences dans la bibliothèque de mathématiques. Voici quelques points à considérer:

  • Oui, les processeurs x86 avec le x87 unité a fnis et fcos instructions. Cependant, ils sont mis en œuvre dans le microcode, et il n'y a pas de raison particulière pourquoi ils doivent être plus rapide qu'une pure mise en œuvre de logiciels.
  • GCC n'a pas de bibliothèque de mathématiques, mais utilise plutôt le système a fourni une. Sur Linux, cela est généralement fournie par la glibc.
  • 32-bit x86 glibc utilise fnis/fcos.
  • x86_64 glibc utilise des implémentations de logiciels à l'aide de la SSE2 unité. Pendant longtemps, cela a été beaucoup plus lente que la version 32 bits de version de la glibc qui viens d'utiliser le x87 instructions. Toutefois, des améliorations ont (un peu récemment été faites, de sorte que selon la version de la glibc vous avez la situation n'est peut être pas mal plus comme il l'habitude d'être.
  • Le compilateur Intel suite est béni avec une TRÈS grande bibliothèque de mathématiques (libimf). En outre, il comprend vectorisé transcendantale fonctions mathématiques, ce qui permet d'accélérer le rythme de boucles avec ces fonctions.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X