11
votes

Une instruction de décalage est-elle plus rapide qu'une instruction imul?

lequel est plus rapide - xxx

ou xxx

combien de cycles d'horloge imul prends quand comparé à l'instruction de décalage?


5 commentaires

Des questions similaires ont été posées avant - le résultat final: "Regardez la documentation de l'instruction fournie par la fabrication" (cela variera selon le modèle) et "c'est compliqué" (CPU pipeline de commandement supérieur moderne ne peut pas Il suffit d'être compté comme un microprocesseur "traditionnel").


À tout le moins, incluez le processeur cible modèle . Ceci peut réellement mèner à quelque chose de quelque peu intéressant.


Plus les raisons de laisser le compilateur s'inquiéter à ce sujet: L'écriture de la manière standard est plus lisible (pour les humains), et il y a plus de chances que le compilateur fera la bonne chose pour l'architecture à portée de main.


Je ne peux pas dire assez ça: Mesurez-le! Et recherchez vos documents de la CPU.


Vous écrivez en C mais parlez d'ASM. Compiler avec optimisation activée et vous verrez que les compilateurs le font cela pour vous.


4 Réponses :


10
votes

Je dirais, écrivez simplement val = val * 10; ou val * = 10; et laissez le compilateur à s'inquiéter de telles questions.


2 commentaires

+1 "Nous devrions oublier de petites gains d'efficacité, selon environ 97% du temps: l'optimisation prématurée est la racine de tout mal"


Considérant particulièrement que cette optimisation peut être faite facilement par le compilateur si vous le souhaitez (Warren a tout un chapitre sur ce produit dans le délice de Hacker).



65
votes

C'est le 21ème siècle. Le matériel moderne et les compilateurs savent produire un code hautement optimisé. L'écriture de multiplication à l'aide de Changements ne facilitera pas la performance, mais cela vous aidera à produire du code avec des bugs.

Vous vous en avez démontré avec vous-même avec un code multiplié par 12 plutôt que 10.


1 commentaires

+1 pour "Vous avez démontré cela vous-même avec du code multipliant par 12 plutôt que 10". Une réponse la plus excellente!



3
votes

faire des "optimisations" idiotes comme celle-ci à la main dans une langue de haut niveau n'abandonnera que de montrer aux gens que vous êtes hors de contact avec des pratiques de technologie et de programmation modernes.

Si vous écriviez à l'assemblage directement, il serait Consignez-vous de vous inquiéter de cela, mais vous n'êtes pas.

avec qui dit, il y a un quelques cas où le compilateur ne sera pas en mesure d'optimiser quelque chose comme celui-ci. Envisagez un éventail de facteurs multiplicatifs possibles, chacun comprenant exactement 2 bits non nulles, avec code comme: xxx

si le profilage montre que c'est un goulot d'étranglement majeur de votre programme, vous pourriez Envisagez de remplacer cela par: xxx

tant que vous envisagez de mesurer les résultats. Cependant, je soupçonne qu'il est rare de trouver une situation où cela aiderait, ou où il serait même possible. C'est uniquement plausible sur une CPU avec une faible unité multipliée par rapport aux déplacements et au débit d'instructions totales.


2 commentaires

Votre idée de deux quarts de travail pourrait aider sur une CPU avec des multiples multiples très lents, mais des décalages de comptage variables rapides, surtout si x est __ int128 ou même int.4_t sur un processeur 32 bits. (Bien que fait deux changements de précision étendus n'est pas merveilleux non plus non plus.) Le Pentium original d'Intel (P5) avait imul qui prend 9c. Malheureusement, SHL R32, CL prend 4C, donc cette idée est un non-démarreur sur P5. Atom dans l'ordre (pré-Silvermont) a 13C latence (et non pipelined) pour imul r64, r64 , mais 1c latence pour shl r64, cl , donc cela pourrait gagner là.


Surtout si vous emballez les deux points de décalage dans une structure 16 bits, c'est donc au lieu de deux charges distinctes, c'est MOVZX ECX, Word S [I] / SHL RAX, CL / SHR ECX, 8 / ... / Shl RBX, CL / Ajouter RAX, RBX . (Je pense que vous voulez + plutôt que | pour combiner les deux résultats multiples partiels).



8
votes

Dans ce cas, ils prennent probablement la même quantité de cycles, bien que votre "optimisation" manuelle ait besoin d'un registre supplémentaire (qui peut ralentir le code environnant): xxx pré>

vs p >

val = (val<<3) + (val<<1);
lea    (%eax,%eax,1),%edx
lea    (%edx,%eax,8),%eax


0 commentaires