为什么数组元素长度的地址计算可被 2 的幂整除更有效

Why is address calculation for array element lengths divisible by powers of 2 more efficient?

本文关键字:有效 数组元素 地址 计算 为什么      更新时间:2023-10-16

我正在深入研究指针,因为我认为我对指针没有很好的了解,并在维基百科上遇到了以下行:

处理数组时,关键查找操作通常 涉及一个称为地址计算的阶段,该阶段涉及 构造指向数组中所需数据元素的指针。如果 数组中的数据元素的长度可被以下两除 二的幂,这个算术通常更有效。

为什么会这样?

上面的行写在"用途"标题下

乘以 2n 是通过向左移动来完成的。现代处理器可以在单个周期内完成移位(在 x86 中,对于高达 8 或 16 的小移位,内置于地址计算本身中)。在 AMD64 机器上,常规乘法运算需要 4-10 个时钟周期,在现代英特尔处理器上很可能类似。对于两个连续乘法运算的"接近在一起"方式也有限制。

当然,如果数组的大小很大,使用乘法指令并将数据打包得更紧密(不使用填充将数据扩展到 2 大小的幂)可能会更有效,因为缓存效率高

当然,现代编译器很聪明,所以如果需要乘以 X 乘以 12,编译器会生成 (X << 3) + (X << 2) ,例如,这比单个乘法运算更快。

第 i 个元素的地址计算涉及 base + size_of_element * i

当元素的大小是 2 的幂时,比如 size_of_element = 2^m,那么这可以通过 base + (i << m) 来实现。

与先前计算中涉及的乘法相比,移位效率要高得多。

因为偏移量可以用左移而不是乘法计算,但考虑到 CPU 中的流水线数量,我还要说这句话可能已经过时了十年或二十年。

当乘法时,例如必须碰巧找到数组中的第 N 个成员,当您处理 2 的幂时,您可以使用移位运算,这比某些系统上的完全成熟的乘法运算成本更低。