C/C++:乘以或位移然后分割?

前端之家收集整理的这篇文章主要介绍了C/C++:乘以或位移然后分割?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这个问题在这里已经有一个答案:> Is multiplication and division using shift operators in C actually faster?14个
可以这样做的时候,我想知道用一个位移替换单个乘法后跟一个整数除法是否更快.说我有一个int k,我想要乘以2.25.

什么更快?

  1. int k = 5;
  2. k *= 2.25;
  3. std::cout << k << std::endl;

要么

  1. int k = 5;
  2. k = (k<<1) + (k/4);
  3. std::cout << k << std::endl;

产量

  1. 11
  2. 11

两者都给出相同的结果,可以查看this full example.

解决方法

第一次尝试

我定义函数regularmultiply()和bitwisemultiply(),如下所示:

  1. int regularmultiply(int j)
  2. {
  3. return j * 2.25;
  4. }
  5.  
  6. int bitwisemultiply(int k)
  7. {
  8. return (k << 1) + (k >> 2);
  9. }

在使用仪器进行分析时(在2009年Macbook OS X 10.9.2中的XCode中),似乎比常规执行的速度要快两倍.

汇编代码输出似乎证实了这一点,因为大部分时间花费大部分时间用于注册改组和函数返回,而常规的大部分时间都花费在乘法上.

regularmultiply:

bitwisemultiply:

但我的审判时间太短.

第二次尝试

接下来,我尝试使用1000万次乘法执行这两个函数,这次将循环放在函数中,以便所有的函数进入和离开都不会掩盖数字.而这一次,结果是每个方法花了大约52毫秒的时间.因此,至少对于相对较大而不是巨大的计算量,这两个功能大致相同.这让我感到惊讶,所以我决定计算更长和更大的数字.

第三次尝试

这一次,我只有1亿,通过5亿加倍2.25,但比特比实际上出来比普通比较慢.

最后的尝试

最后,我切换了这两个功能的顺序,只是为了看看Instrument中不断增长的cpu图表可能会减慢第二个功能.但是,经常性的表现略好一些:

这是最后的程序是什么样的:

  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5. void regularmultiplyloop(int j);
  6. void bitwisemultiplyloop(int k);
  7.  
  8. int i,j,k;
  9.  
  10. j = k = 4;
  11. bitwisemultiplyloop(k);
  12. regularmultiplyloop(j);
  13.  
  14. return 0;
  15. }
  16.  
  17. void regularmultiplyloop(int j)
  18. {
  19. for(int m = 0; m < 10; m++)
  20. {
  21. for(int i = 100000000; i < 500000000; i++)
  22. {
  23. j = i;
  24. j *= 2.25;
  25. }
  26. printf("j: %d\n",j);
  27. }
  28. }
  29.  
  30. void bitwisemultiplyloop(int k)
  31. {
  32. for(int m = 0; m < 10; m++)
  33. {
  34. for(int i = 100000000; i < 500000000; i++)
  35. {
  36. k = i;
  37. k = (k << 1) + (k >> 2);
  38. }
  39. printf("k: %d\n",k);
  40. }
  41. }

结论

那么我们可以说这一切呢?有一点我们可以肯定地说,优化编译器比大多数人更好.此外,当有很多计算时,这些优化显示出更多的优势,这是您真正想要优化的唯一时间.因此,除非您在汇编中编码优化,否则将乘法更改为位移可能不会有太大帮助.

考虑应用程序的效率总是很好,但微型效率的提高通常不足以保证您的代码不易读取.

猜你在找的C&C++相关文章