101 votes

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 qui est préférable d'utiliser. Une opération est-elle fondamentalement plus rapide que l'autre?

72voto

couling Points 2445

Je ne comprends pas pourquoi cela a été voté tellement. C'est une bonne question.

À l'université, j'ai appris que la division d'une durée de six fois celle de la multiplication. La réelle timings sont dépendants de l'architecture, mais en général, la multiplication ne sera jamais plus lente, voire aussi lente que la division. Toujours optimiser votre code vers l'utilisation de multiplication si les erreurs d'arrondi permettre.

Ainsi, dans un exemple:

for (int i=0; i<arraySize; i++) {
    a[i] = b[i] / x;
}

ce serait généralement plus lent que

y=1/x;
for (int i=0; i<arraySize; i++) {
    a[i] = b[i] * y;
}

Bien sûr, avec les erreurs d'arrondi, vous perdrez un peu de précision avec la seconde méthode, mais si vous êtes à plusieurs reprises le calcul de x=1/x; c'est peu probable de causer beaucoup de problème.

Edit:

Juste pour la référence. J'ai creusé un tiers de la comparaison de fonctionnement timings par une recherche sur Google.

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

Regardez les chiffres sur MUL et DIV. Cela indique que les différences entre 5 et 10 fois selon le processeur.

34voto

Mats Petersson Points 70074

Il est très probable que le compilateur va convertir une fracture à une multiplication dans ce cas, s'il "pense" c'est plus rapide. En divisant par 2 en virgule flottante peut également être plus rapide que les autres float divise. Si le compilateur n'a pas à le convertir, il PEUT être plus rapide d'utiliser multiplier, mais pas certain - dépend du processeur lui-même.

Le gain manuellement, à l'aide de multiplier au lieu de fracture peut être très grande dans le cas où le compilateur ne peut pas déterminer qu'il est "sûr" pour faire e.g 0.1 ne peuvent pas être stockés exactement comme de 0,1 à un nombre à virgule flottante, il devient 0.10000000149011612). Voir ci-dessous pour les chiffres sur les processeurs AMD, ce qui peut être considéré comme représentatif de la classe.

Pour savoir si votre compilateur n'est ce bien ou pas, pourquoi ne pas vous écrire un peu de code à l'expérimentation. Assurez-vous que vous l'écrivez, de sorte que le compilateur n'est pas simplement calculer une valeur constante et efface tous les calculs en boucle tho'.

Edit:

AMD optimisation de guide pour la Famille 15h processeurs, fournir des chiffres pour fdiv et fmul - 42 et 6, respectivement. L'ESS sont des versions un peu plus près, 24 (unique) ou 27 (double) cycles pour DIVPS, DIVPD DIVSS et DIVSD (fracture), et 6 cycles pour toutes les formes de se multiplier.

À partir de la mémoire, du processeur Intel chiffres ne sont pas loin.

29voto

ouah Points 75311

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 est bien conscient de ce type de micro-optimisations.

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