Pourquoi ne pas GCC optimiser un*un*un*un*un*un (a*a*a)*(a*a*a)?

Je fais un certain optimisation numérique sur une application scientifique. Une chose que j'ai remarqué, c'est que GCC permettra d'optimiser l'appel pow(a,2) par la compilation en a*a, mais l'appel pow(a,6) n'est pas optimisé et fait appel une fonction de la bibliothèque pow, ce qui a considérablement ralentit les performances. (En revanche, Le Compilateur Intel C++ , exécutable icc, permettra d'éliminer l'appel de la bibliothèque pour pow(a,6).)

Ce que je suis curieux de savoir, c'est que quand j'ai remplacé pow(a,6) avec a*a*a*a*a*a à l'aide de GCC 4.5.1 et options "-O3 -lm -funroll-loops -msse4", il utilise 5 mulsd instructions:

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13

alors que si j'écris (a*a*a)*(a*a*a), il va produire

movapd  %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm14, %xmm13
mulsd   %xmm13, %xmm13

qui réduit le nombre d'instructions de multiplication de 3. icc a un comportement similaire.

Pourquoi les compilateurs ne pas reconnaître cette optimisation truc?

  • Ce n' "reconnaissant pow(a,6)" signifie?
  • Je suis surpris gcc ne pas optimiser ce. Les années 1970 compilateur FORTRAN j'ai utilisé sur CDC Cyber n'a ce genre de transformation, même sans sélectionner d'optimisation. Je pense que les Unix V6 (c. 1978) C compilateur fait lorsque l'optimisation est activée, si de nombreuses optimisations il n'a été à enregistrer le code de l'espace, une denrée précieuse en ces jours.
  • Euh... vous savez que aaaaaa et (aaa)*(aa*a) ne sont pas la même chose avec des nombres à virgule flottante, n'est-ce pas? Vous aurez à utiliser -funsafe-math ou -ffast-math ou quelque chose pour que.
  • Je vous suggère de lire "Ce que Chaque informaticien Devriez Savoir Sur l'Arithmétique à virgule Flottante" par David Goldberg: download.oracle.com/docs/cd/E19957-01/806-3568/... après quoi vous aurez une compréhension plus complète de la fonctionnalité tar pit que vous avez juste entré en!
  • Une question parfaitement justifiée. 20 ans auparavant, j'ai posé la même question d'ordre général, et en écrasant que seul goulet d'étranglement, réduit le temps d'exécution d'une simulation de Monte Carlo à partir de 21 heures à 7 heures. Le code dans la boucle interne a été exécuté 13 milliards de fois dans le processus, mais il a obtenu la simulation en cours de nuit de la fenêtre. (voir la réponse ci-dessous)
  • Peut-être jeter (a*a)*(a*a)*(a*a) dans le mélange, trop. Même nombre de multiplications, mais probablement plus exacte.
  • Pour commencer, comment cela est optimisé dépend grandement de ce type a a...
  • Shameless plug: en plus de Goldberg de papier, je suggère la lecture de la mine, hal.archives-ouvertes.fr/file/index/docid/281429/filename/...
  • en fait, un bon optimiseur pourrait prendre un peu plus loin. a*a seulement besoin d'être effectuée qu'une fois. Les résultats pouvaient être réutilisés assez facilement à le réduire à seulement 3 opérations de multiplication.
  • Oui, 3, exactement le même que (a*a*a)*(a*a*a), c'est ce que j'ai proposé comme une alternative. Qu'essayez-vous de dire?

InformationsquelleAutor xis | 2011-06-21