Why is address calculation for array element lengths divisible by powers of 2 more efficient?
我正在深入研究指针,因为我认为我对指针没有很好的了解,在维基百科上遇到了以下几点:
When dealing with arrays, the critical lookup operation typically
involves a stage called address calculation which involves
constructing a pointer to the desired data element in the array. If
the data elements in the array have lengths that are divisible by
powers of two, this arithmetic is usually much more efficient.
为什么会这样?
以上行写在标题"用途"下。
- 在维基百科上应该有一个需要引用的标志
- 如今,乘法并没有比移位慢多少。除非该声明是指lea指令。但这只会产生非常小的二次幂。(我想最多4或8个)
- 我同意这种差异在最先进的处理器中可以忽略不计。但是,除了这些处理器,还有各种各样的计算设备,比如运行程序的低端微控制器。在大多数这些设备中,移位和乘法的区别是显著的。
- 可能相关,但结论相反-stackoverflow.com/questions/11413855/…
乘以2n就是向左移动。现代处理器可以在一个周期内进行移位(在x86中,对于地址计算本身内置的8或16个小移位)。在AMD64机器上,常规的乘法运算需要4-10个时钟周期,而在现代Intel处理器上则很可能类似。对于如何"紧密结合"两个连续的乘法运算也有限制。
当然,如果数组的大小相当大,那么使用乘法指令并将数据压缩得更紧密(不使用填充将数据扩展到2倍大小)可能会更有效,因为缓存效率很高。
当然,现代编译器很聪明,所以如果需要x乘以12,编译器将生成(X << 3) + (X << 2),这比单次乘法运算要快。
- "将数据打包得更紧密"是什么意思?
- 自核心2以来,英特尔处理器上的整数乘法一直是3个周期的延迟,吞吐量为1/周期。移位为1个周期延迟和2个/周期。所以是的,换档速度还是更快。但不多。
- @用户2485710:我已经编辑了,以便更清楚地解释"更紧密地打包数据"。神秘:是的,我认为1/周期比延迟更重要-特别是在二维数组中,最里面的维度和元素大小都不是2^n。
- @奇怪的是,对于内核2上的64位,SHL的吞吐量是IMUL的4倍,延迟是IMUL的5倍。
- @那么伊莎莉亚或者阿涅尔雾是错误的或者GMP是错误的。我从Agner Fog的桌子上找到了我的号码。
- @神秘不是错的,它列出了完全相同的差异。也许您没有看到64位操作?查看imul中的r64、r64
- @你说得对。我在看32位乘法。但看起来甚至64位乘法在尼哈勒姆也下降了。
第i个元素的地址计算涉及base + size_of_element * i。
当元素的大小是2的幂时,假设元素的大小为2^m,那么这可以用base + (i << m)实现。
与前面计算中涉及的乘法相比,移位更有效。
- @PS06756不,那句话是关于元素大小的。
- @哈罗德,我的错,我会改正的。
- @killands'lea'进行加法和偏移计算。它既不能与乘法相提并论,也不能与移位相提并论。我在20世纪80年代初测试了乘法和移位,结果慢了10倍。同样,这不是一个有争议的声明。如果你能制造出一个成本不低的系统,请这样做。
- @基利安兹,我没说你不应该考虑,我说你不应该比较。苹果和桔子。你不能指责别人散布半真半假的真理。我进一步注意到,你不断要求引文,而不是你自己的,即使被要求。
当乘法时,比如在数组中偶然找到第n个成员时,当你处理两个幂的时候,你可以使用移位运算,这比在某些系统上执行完全乘法运算成本最低。
- 我只是按要求解释维基百科页面上写的东西——由原始作者提供参考资料。
- @基利安兹,我不同意。这不是一个有争议的说法。"成本更低"和"不注意区别"之间有区别。
- 我修改了答案说"在某些系统中"…你将如何回答这个问题?
- 黄鼠狼的话:)举个例子,像这样:instlatx64.atw.hu移位明显比imul更快。lea最坏的情况和imul一样糟糕,你必须做的比imul还要多,所以lea仍然获胜。至于这是否真的起了作用,那是另外一回事。
- 我能在这一点上指出,在答案中包含任何这些信息都不会帮助提出问题的人:)
因为偏移量可以用左移位而不是乘法来计算,但是我也会说,考虑到CPU中的流水线数量,这句话可能已经过时了10到20年。