5

在大多数现代 64 位处理器(例如 Intel Core 2 Duo 或 Intel i7 系列)上,x86_64 命令mulq及其变体的速度是否取决于操作数?例如,乘法11 * 13会比11111111 * 13131313? 还是总是需要最坏情况的时间?

4

3 回答 3

6

TL; DR:不。恒定长度整数数学运算(除法,它是非线性的)消耗恒定数量的周期,无论操作数的数值如何。

mulq接受两个 QWORD 参数。

这些值以 little-endian 二进制格式(由 x86 架构使用)表示,如下所示:

1011000000000000000000000000000000000000000000000000000000000000 =       13
1000110001111010000100110000000000000000000000000000000000000000 = 13131313

处理器将这两者视为相同的“大小”,因为它们都是 64 位值。

因此,无论操作数的实际数值如何,循环计数都应该始终相同。

更多信息:

有超前零预期和超前零检测[ 1 ][ 2 ] (LZA/LZD) 的概念可用于加速浮点运算。

然而,据我所知,没有主流处理器采用这两种方法中的任何一种来进行整数运算。这很可能是由于大多数整数算术(在这种情况下为乘法)的简单性。LZA/LZD 的开销可能根本不值得,因为简单的整数数学电路无论如何都可以在更短的时间内完成完全乘法。

于 2012-06-05T19:49:38.117 回答
2

我没有任何关于手的参考,但我会把钱放在延迟/吞吐量上,因为它不会改变操作数的值。否则,安排将是一场噩梦。

于 2012-06-05T19:47:19.627 回答
2

几十年来,Agner Fog 一直在发布指令时序表。他 2019 年 8 月的表格证实了我的预期:现代笔记本电脑和台式电脑中的 CPU 芯片的整数乘法单元具有不变的时序。这些速度非常快,而且相当耗电。

CPU 的设计空间对于智能手机等电池受限的设备有很大的不同。在这样的设备上,整数乘法可以在具有可变时序的微编码循环中实现。

在(大约)2016 年,Thomas Pornin 谈到了可变延迟乘法指令对他的 SSL/TLS 库的设计带来的“问题”:

“...... CPU 中的整数乘法操作码可能会或可能不会在恒定时间内执行;如果不这样做,使用此类操作的实现可能会表现出取决于所涉及数据的执行时间变化,从而可能泄露秘密信息......当一个CPU 具有非恒定时间乘法操作码,执行时间取决于一个或两个操作数的大小(以整数形式)。例如,在 ARM Cortex-M3 上,umull 操作码需要 3 到 5 个周期才能完成,仅当两个操作数的数值都小于 65536 时才采用“短”计数(3 或 4)...一般而言,英特尔 x86 CPU 自第一个奔腾时代以来都提供恒定时间乘法。这不一定成立对于其他供应商,尤其是早期的威盛 Nano。” 2

于 2020-05-11T04:23:37.830 回答