Est la multiplication et la division à l'aide d'opérateurs de décalage dans C vraiment le plus rapide?

De Multiplication et de division peut être réalisé en utilisant des bits les opérateurs, par exemple

i*2 = i<<1
i*3 = (i<<1) + i;
i*10 = (i<<3) + (i<<1)

et ainsi de suite.

Est-il réellement plus rapide d'utiliser le dire (i<<3)+(i<<1) à multiplier par 10 que l'utilisation de i*10 directement? Est-il une sorte d'entrée qui ne peut pas être multiplié ou divisé de cette manière?

  • En fait, bon marché division par une constante d'autre qu'une puissance de deux est possible, mais difficile de sujet auquel vous n'êtes pas de faire la justice avec "/Division ... /divisé" dans votre question. Voir par exemple hackersdelight.org/divcMore.pdf (ou obtenir le livre "Hacker s delight" si vous le pouvez).
  • Ça sonne comme quelque chose qui pourrait facilement être testé.
  • Comme d'habitude, ça dépend. Une fois, j'ai essayé ce en assembleur sur un processeur Intel 8088 (IBM PC/XT) où une multiplication pris un bazillion horloges. Changements et ajoute exécuté beaucoup plus rapide, de sorte qu'il semblait être une bonne idée. Cependant, tout en multipliant l'unité de bus est libre de remplir l'instruction de la file d'attente et la prochaine instruction a pu alors commencer immédiatement. Après une série de changements et ajoute l'instruction file d'attente est vide et le CPU aurait à attendre la prochaine instruction à être récupérées à partir de la mémoire (un octet à la fois!). Mesurez, mesurez, mesurez!
  • il était donc plus de difficultés à la mise en œuvre de la nouvelle version alors il valait la peine ou vous êtes-vous l'utiliser?
  • Aussi, méfiez-vous que le droit-le déplacement est uniquement définie pour les entiers non signés. Si vous avez un entier signé, il n'est pas défini si 0 ou le bit le plus élevé sont complétées à partir de la gauche. (Et n'oubliez pas le temps qu'il faut pour quelqu'un d'autre (même vous) pour lire le code d'un an plus tard!)
  • Non, j'ai fini à l'aide de la multiplier, parce que c'était la manière la plus rapide pour l'ensemble de la routine. Le 8088 a été limitée par le bus 8 bits, de sorte que la taille du code est souvent plus important que le nombre d'horloges pour chaque instruction.
  • En fait, un bon compilateur optimisant la volonté de mettre en œuvre la multiplication et de la division avec les changements quand ils sont plus rapides.
  • G. Dans le [s|b]ad vieux jours avant une bonne optimisation des compilateurs et des processeurs rapides, j'ai utilisé mon propre "10 fois" de routine (maj une fois & enregistrer, puis sur maj deux fois plus et ajouter à la valeur enregistrée). Aujourd'hui, il ne vaut pas la peine de déranger, mais à l'époque, il fait la différence entre les utilisateurs d'obtenir un rapport immédiatement, ou aller pour une pause café pendant qu'ils attendaient.
  • Il convient de mentionner que l'optimisation est appelée réduction de la résistance.
  • Il n'y a pas une telle chose comme "mieux". Sur un 8 broches du microcontrôleur, vous pouvez optimiser pour moins d'instructions. Si le processeur est un vecteur de processeur que vous craignent peut-être que vous pouvez faire 16 multiplications dans l'enseignement et la nécessité d'incorporer votre algorithme sur un grand vecteur de moteur. Comme tout le monde le dit, de rendre votre code dire quoi faire, pas comment le faire. Si vous connaissez un code spécifique chemin prend 90% de votre temps CPU, puis le bas niveau de stuff SI les mesures dire que ça aide. Autre chose serait une perte de temps qui pourrait être consacré en fait de l'optimisation de choses.
  • Je ne suis pas sûr que j'ai jamais vu un compilateur où divisant signé un nombre par une puissance de 2 n'a pas été plus lent que de faire une maj de droite. On pourrait dire que si les dividendes ne seront jamais négatifs que l'on jette de la non signé et de faire la division, mais qui peuvent causer des bizarreries de son propre.
  • Je suis un peu en retard à cette discussion, mais un récent test de la curiosité a montré que int64 division était d'environ 8 fois plus lent que bitshifting mais int64 de multiplication a été le même. Il est intéressant de noter, int32 division produit les mêmes résultats que int32 bitshifting. J'ai couru ce test très impromptu en mode de débogage, de sorte que ces résultats pourraient ne pas être représentatifs de l'objet dans l'application.

InformationsquelleAutor eku | 2011-06-15