问题示例:
计算123 * 456比计算123456 * 7890快吗?还是速度相同?
我想知道32位无符号整数,但我不会忽略其他类型(64位,有符号,浮点等)的答案。如果不同,会有什么不同?这些位是否为0/1?
编辑:如果它有所不同,我应该澄清我指的是任何数字(两个低于100的随机数与两个高于1000的随机数)
答案 0 :(得分:4)
对于内置类型至少达到架构的字大小(例如现代PC上的64位,过去几十年中大多数低成本通用CPU上的32位或16位),对于每个编译器/我听说过的实现/版本和CPU, 用于特定整数大小乘法的CPU操作码需要一定的时钟周期而不管涉及的数量 。不同大小的数据的乘法在某些CPU上的表现不同(例如,AMD K7对于16位IMUL有3个周期的延迟,而对于32位有4个周期)。
在某些架构和编译器/标志组合上,类似long long int
的类型可能比CPU操作码在一条指令中可以操作的位数更多,因此编译器可能会发出用于分阶段进行乘法的代码,它比CPU支持的类型的乘法要慢。但同样,在更广泛类型的运行时存储的小值不太可能被处理 - 或执行 - 与更大的值不同。
所有这一切,如果一个或两个值是编译时常量,编译器就能够避免CPU乘法运算符并优化为某些值的加法或位移运算符(例如1
显然是否-op,任一方0 ==> 0结果,* 4
有时可以实现为<< 2
)。没有什么特别的停止技术,比如位移用于更大的数字,但是这些数字的较小百分比可以被优化到相同的程度(例如,有两个更多的权力 - 其中乘法可以是使用左移位进行 - 介于0和1000之间,而不是介于1000和2000之间)。
答案 1 :(得分:2)
这高度依赖于处理器架构和模型。
在过去(1980-1990)中,两个数字中的数字是一个因素 - 越多,经过符号调整后乘以的时间越长,所以乘以-1不是&#39 ; t慢于乘以1,但乘以32767(15个)明显慢于乘以17(2个)]。这是因为乘法基本上是:
unsigned int multiply(unsigned int a, unsigned int b)
{
res = 0;
for(number of bits)
{
if (b & 1)
{
res += a;
}
a <<= 1;
b >>= 1;
}
}
在现代处理器中,乘法无论哪种方式都相当快,但64位乘法可以是一个时钟周期,也可以比32位值慢两倍。仅仅因为现代处理器可以承受&#34;在单个周期中放下完成这个的整个逻辑 - 无论是在晶体管本身的速度,还是晶体管占用的区域。
此外,在过去,经常有指示做16 x 16 - &gt; 32位结果,但如果您想要32 x 32 - > 32(或64),编译器必须调用库函数[或内联这样的函数]。今天,我不知道任何现代高端处理器[x86,ARM,PowerPC]至少不能做64 x 64 - &gt; 64,有些做64 x 64 - &gt; 128,所有这些都在一条指令中(并不总是单个循环)。
请注意,我完全忽略了这样一个事实,即如果数据在缓存中是一个重要因素&#34;。是的,这是一个因素 - 它有点像在以200公里/小时的速度行驶时忽略风阻 - 它根本不是你在现实世界中忽视的东西。但是,这对于这次讨论来说并不重要。就像制造跑车关心空气动力学的人一样,让复杂(或简单)的软件快速运行需要一定程度的关注缓存内容。
答案 2 :(得分:-3)
对于所有意图和目的,速度相同(即使计算速度存在差异,它们也是无法估量的)。如果您有好奇心,请参考以下不同CPU操作的参考:http://www.agner.org/optimize/instruction_tables.pdf。