La multiplication est-elle plus rapide que la division float?

En C / C ++, vous pouvez configurer le code suivant:

double a, b, c; ... c = (a + b) / 2; 

Cela fait exactement la même chose que:

 c = (a + b) * 0.5; 

Je me demande lequel est préférable d’utiliser. Une opération est-elle fondamentalement plus rapide que l’autre?

La multiplication est plus rapide que la division. A l’université, on m’a enseigné que la division prenait six fois celle de la multiplication. Les timings réels dépendent de l’architecture, mais en général, la multiplication ne sera jamais plus lente ni même aussi lente que la division. Optimisez toujours votre code en utilisant la multiplication si les erreurs d’arrondi le permettent.

Donc, dans un exemple, cela serait généralement plus lent …

 for (int i=0; i 

... que ça ...

 y=1/x; for (int i=0; i 

Bien sûr, avec les erreurs d'arrondi, vous perdrez un peu de précision avec la seconde méthode, mais à moins que vous ne calculiez de manière répétée x=1/x; il est peu probable que cela cause beaucoup de problèmes.

Modifier:

Juste pour référence. J'ai déterré une comparaison tierce des temps de fonctionnement en effectuant une recherche sur Google.

http://gmplib.org/~tege/x86-timing.pdf

Regardez les chiffres sur MUL et DIV. Cela indique des différences de 5 à 10 fois selon le processeur.

La multiplication en virgule flottante prend généralement moins de cycles que la division en virgule flottante. Mais avec les opérandes littéraux, l’optimiseur connaît bien ce type de micro-optimisations.

Il est fort probable que le compilateur convertira une division en multipliant dans ce cas, s’il “pense” que c’est plus rapide. La division par 2 en virgule flottante peut également être plus rapide que les autres divisions flottantes. Si le compilateur ne le convertit pas, il PEUT être plus rapide à utiliser multiplié, mais pas certain – dépend du processeur lui-même.

Le gain de l’utilisation manuelle de la multiplication au lieu de la division peut être très important dans les cas où le compilateur ne peut pas déterminer qu’il est “sûr” de le faire (par exemple, 0.1 ne peut pas être stocké exactement comme 0.1 en virgule flottante ). Voir ci-dessous les chiffres sur les processeurs AMD, qui peuvent être considérés comme représentatifs de la classe.

Pour savoir si votre compilateur le fait bien ou pas, pourquoi ne pas écrire un peu de code pour expérimenter. Assurez-vous de l’écrire pour que le compilateur ne calcule pas simplement une valeur constante et supprime tous les calculs dans la boucle, même si cela ne se produit pas.

Modifier:

Le guide d’optimisation d’AMD pour les processeurs Family 15h, fournit des chiffres pour fdiv et fmul – 42 et 6 respectivement. Les versions SSE sont un peu plus proches, 24 cycles (simples) ou 27 (doubles) pour DIVPS, DIVPD DIVSS et DIVSD (division), et 6 cycles pour toutes les formes de multiplication.

De mémoire, les chiffres d’Intel ne sont pas si éloignés.