This question already has answers here:
Is multiplication and division using shift operators in C actually faster?
(19个回答)
已关闭6年。
在可能的情况下,我想知道用位移位后跟整数除法替换单个乘法是否更快。假设我有一个整数k,我想将其乘以2.25。
什么更快?
或者
输出
两者给出相同的结果,您可以检查this full example。
使用Instruments进行性能分析(在2009 Macbook OS X 10.9.2上的XCode中)后,
汇编代码输出似乎证实了这一点,
常规乘以:
按位乘以:
但是我的审判时间太短了。
第二次尝试
接下来,我尝试用1000万次乘法执行两个函数,这一次将循环放入函数中,以使所有函数进入和离开都不会掩盖数字。这次,结果是每种方法花费了大约52毫秒的时间。因此,至少对于相对较大但不是巨大数量的计算,这两个函数大约需要相同的时间。这让我感到惊讶,因此我决定计算更长的时间并使用更大的数字。
第三次尝试
这次,我只将1亿乘以5亿乘以2.25,但是
最后的尝试
最后,我切换了这两个功能的顺序,只是为了查看Instruments中不断增长的CPU图形是否正在减慢第二个功能的运行速度。但是,
最终程序如下所示:
结论
那么我们能怎么说呢?我们可以肯定地说的一件事是,优化编译器比大多数人要好。而且,当存在大量计算时,这些优化甚至会更多地展现出来,这是您唯一真正想进行优化的时间。因此,除非您在汇编中编写优化代码,否则将乘法更改为位移可能不会有多大帮助。
考虑应用程序的效率总是很不错的,但是微效率的提高通常不足以保证代码的可读性。
(19个回答)
已关闭6年。
在可能的情况下,我想知道用位移位后跟整数除法替换单个乘法是否更快。假设我有一个整数k,我想将其乘以2.25。
什么更快?
int k = 5;
k *= 2.25;
std::cout << k << std::endl;
或者
int k = 5;
k = (k<<1) + (k/4);
std::cout << k << std::endl;
输出
11
11
两者给出相同的结果,您可以检查this full example。
最佳答案
第一次尝试
我定义了函数regularmultiply()
和bitwisemultiply()
,如下所示:
int regularmultiply(int j)
{
return j * 2.25;
}
int bitwisemultiply(int k)
{
return (k << 1) + (k >> 2);
}
使用Instruments进行性能分析(在2009 Macbook OS X 10.9.2上的XCode中)后,
bitwisemultiply
的执行速度似乎比regularmultiply
快约2倍。汇编代码输出似乎证实了这一点,
bitwisemultiply
将其大部分时间用于寄存器改组和函数返回,而regularmultiply
则将其大部分时间用于乘法。常规乘以:
按位乘以:
但是我的审判时间太短了。
第二次尝试
接下来,我尝试用1000万次乘法执行两个函数,这一次将循环放入函数中,以使所有函数进入和离开都不会掩盖数字。这次,结果是每种方法花费了大约52毫秒的时间。因此,至少对于相对较大但不是巨大数量的计算,这两个函数大约需要相同的时间。这让我感到惊讶,因此我决定计算更长的时间并使用更大的数字。
第三次尝试
这次,我只将1亿乘以5亿乘以2.25,但是
bitwisemultiply
的输出速度实际上比regularmultiply
稍慢。最后的尝试
最后,我切换了这两个功能的顺序,只是为了查看Instruments中不断增长的CPU图形是否正在减慢第二个功能的运行速度。但是,
regularmultiply
的性能略好一些:最终程序如下所示:
#include <stdio.h>
int main(void)
{
void regularmultiplyloop(int j);
void bitwisemultiplyloop(int k);
int i, j, k;
j = k = 4;
bitwisemultiplyloop(k);
regularmultiplyloop(j);
return 0;
}
void regularmultiplyloop(int j)
{
for(int m = 0; m < 10; m++)
{
for(int i = 100000000; i < 500000000; i++)
{
j = i;
j *= 2.25;
}
printf("j: %d\n", j);
}
}
void bitwisemultiplyloop(int k)
{
for(int m = 0; m < 10; m++)
{
for(int i = 100000000; i < 500000000; i++)
{
k = i;
k = (k << 1) + (k >> 2);
}
printf("k: %d\n", k);
}
}
结论
那么我们能怎么说呢?我们可以肯定地说的一件事是,优化编译器比大多数人要好。而且,当存在大量计算时,这些优化甚至会更多地展现出来,这是您唯一真正想进行优化的时间。因此,除非您在汇编中编写优化代码,否则将乘法更改为位移可能不会有多大帮助。
考虑应用程序的效率总是很不错的,但是微效率的提高通常不足以保证代码的可读性。
关于c++ - C/C++ : Multiply,或位移位然后除法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23984551/
10-11 15:10