性能比较:64位和32位乘法

4
我正在使用一款Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz处理器,想知道为什么64位数的乘法比32位数慢。我已经用C语言进行了测试,并发现它需要两倍的时间。
我原以为它需要相同的时间,因为CPU使用本机64位寄存器,数字的宽度不应该有关系(只要它们适合64位寄存器)。
请问有人能解释一下吗?

你确定你正在编译为64位吗? - Boann
@Boann 大多数实现 x86-64 的处理器仍然具有更快的 32 位乘法。例如,请参见 http://www.agner.org/optimize/instruction_tables.pdf 中第 12 页,了解 32 位和 64 位 IMUL 之间时间差异的一个例子。 - Pascal Cuoq
1
@Boann 错误的页面!(那是针对一个旧的处理器,其乘法仅限于32位。尽管如此,它仍然比16位乘法快)。请尝试查看第22页,了解在实现x86-64的处理器上进行64位与32位IMUL的区别。 - Pascal Cuoq
2
现代核心速度非常快。但在程序中,这并不是典型的限制,因为这些快速核心必须处理极其缓慢的内存。使用64位乘法时,有一些期望您移动两倍的数据,当真正的瓶颈是内存时,这当然会变得两倍慢。这只是一个简单的解释,还有很多其他的。没有必要不展示您的代码,这样您可以获得准确的答案,而不是猜测。 - Hans Passant
最好展示汇编代码。此外,现代的CPU在有机会时很可能能够并行处理两个32位操作,使用与单个64位操作相同的逻辑电路。 - hyde
这是内存的问题。我从堆上的巨大数组中读取数字。正如Hans在评论中解释的那样,对于更大的整数,这将持续两倍的时间。如果不从内存中读取数字(而是从随机生成的数字中生成),差异会小得多。剩下的差异可能是因为在32位寄存器上进行的计算比64位寄存器快一到两个周期。非常感谢所有的评论和答案。 - firefexx
2个回答

7
在x86-64指令集中,有专门的指令来表示您只想将两个32位量相乘。一条指令可能看起来像IMUL %EBX, %ECX,在x86-64汇编的某种方言中,与64位乘法IMUL %RBX, %RCX不同。
因此,处理器知道您只想相乘32位量。这种情况经常发生,处理器的设计者确保内部电路在这种更容易的情况下会优化提供更快的答案,就像你更容易地将3位数乘以6位数一样。这种差异可以在Agner Fog测量的时间表中看到,并在他的全面的汇编优化资源中描述。
如果您的编译器针对旧的32位IA-32指令集,则32位和64位乘法之间的差异甚至更大。编译器必须使用仅用于32位乘法的指令来实现64位乘法,使用其中四个(如果仅计算结果的64个最低有效位,则为三个)。
在这种情况下,64位乘法可能比32位乘法慢三到四倍。

0

我认为这里可能会出现一个问题,因为64位乘法。

实际上,对于两个32位数字的乘法,结果将最大为64位。但是,如果乘以两个64位数字,则乘积可能为128位,在所有情况下都将大于64位!

在8086微处理器中,如果您使用8位数字和16位数字执行相同的操作,您将遇到CPU寄存器必须从AX寄存器和DX寄存器存储的情况(如果您知道汇编语言缩写)。

因此,我认为这可能会增加计算时间!我认为这就是使您的64位乘法变慢的原因!


猜测不是答案,也许这应该是一条评论。 - ErstwhileIII
AX和DX是16位寄存器。并不是所有的64位乘法都会在结果中产生128个有效位,这是肯定的。2和3操作数的mul指令会丢弃高位比特。 - Gene
AX和DX是16位的,但在x86_64系统中它们可能会有相同的情况。看来我忘了提及8086系统,我给出的这个例子是针对8086微处理器的!我正在添加这一点。谢谢! - Am_I_Helpful
@Gene- 我之前的回答已经提到了,并不是所有的64位乘法都是128位长,但肯定大于64位! - Am_I_Helpful

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接