现代 ARM/ARM64 CPU 中的桶形移位器是如何实现的?

问题描述 投票:0回答:1

ARM 有一个桶形移位器,可用于移位指令的第二个操作数。可以这样写

add    x0, x0, x1, lsl #2

而不是

lsl    x1, x1, #2
add    x0, x0, x1

我找到了一些旧 ARM CPU 的文档(例如 wikichip 上的 ARM2 页面),这似乎表明指令的第二个操作数在到达 ALU 之前要经过桶形移位器。

但是,我无法在更新的 CPU 上找到相同的信息。例如,Cortex-A76 的Wikichip 页面根本没有提到桶形移位器,并且核心图也没有显示专用的桶形移位器单元。

现代 ARM/ARM64 CPU 上是否仍然有专用的桶形移位器单元,或者它们是否使用常规 ALU 单元? (我对 ARM 和 ARM64 都感兴趣,但如果答案必须是特定于 CPU 的,那么就说 Cortex-A76)

我问这个问题是因为我想知道使用桶形移位器进行重复计算是否/何时有意义。例如,考虑这个函数:

int f(int* arr1, long int offset, int repl) {
  int a = arr1[offset];
  arr1[offset] = repl;
  return a;
}

是否应该在汇编中实现

ldr     w3, [x0, x1, lsl #2]
str     w2, [x0, x1, lsl #2]

或与

lsl     x1, x1, #2
ldr     w3, [x0, x1]
str     w2, [x0, x1]

GCC 13.2 似乎更喜欢前者,但 GCC 14.0 Trunk 更喜欢后者。 我猜测桶形移位器的具体实现会影响哪一个更快。 (对于这个问题,我们假设套准压力不是问题)

arm cpu-architecture arm64
1个回答
0
投票

这里是一些关于桶式移位器的信息。请注意,ARMv2 是在 1980 年设计的,Verilog 和 VHDL 等技术刚刚被发明。这时设计师审视了每一个大门。 “桶形变速装置”是一种执行动态变速操作的技术。有多种方法可以实现这一点。硬件中的固定移位只是从源到目的地的线路,用于执行移位/旋转。

现代 ARM/ARM64 CPU 上是否仍然有专用的桶形移位器单元,或者它们是否使用常规 ALU 单元?

虽然我不知道,我无法想象“奉献的东西”?很可能有“shift.v”或类似的东西。完成初步设计后,您可以根据需要制作任意数量的“shift.v”饼干模具。工具现在将重新实现/连接“shift.v”模块所做的任何事情。因此,每个加载存储单元可以具有移位器和/或支持移位寄存器的所有操作数。在一个设计中,一个寄存器也可以有多个副本。在 20 世纪 80 年代,人们可能会为变速杆而出汗。 CPU 需要多个周期才能完成所有工作。 RAM从来都不是真正的问题(与速度有关)。今天,我认为 CPU 中可能有数千个移位器电路,并且 CPU 可以等待外部 RAM 的数千个周期。

是否应该在汇编中实现

对于,

  1. 电源
  2. 代码大小
  3. 执行速度

第 2,3 项可能是并列的。除非 CPU 的文档说明这需要额外的周期(对于 Cortex-A 设计或更高版本不太可能),否则复制移位是最好的方法。

单次移位完全有可能节省电量,但不太可能,因为 CPU 内部的大量开销会被额外的指令读取耗尽。

比编译器级别的转换成本更大的是管理数据流。编译器会做不同的事情,具体取决于它判断事物的重要性。如果您没有在循环中使用此代码,那么不相关的代码部分可能会导致替代指令选择。我认为依赖编译器是错误的(对于这个问题主题)。您需要查阅感兴趣的CPU的技术参考手册。

一般最佳实践是,

  1. 选择读起来最好的代码。
  2. 构建了成功的原型。
  3. 分析系统。
  4. 然后才在需要的地方进行优化。

第四项通常只有在您拥有完整的实施例时才能得到回答,因为许多系统设备(缓存、RAM、CPU)相互作用会影响性能。此外,当/如果代码移动到另一个平台时,过早的优化也会限制代码。最常见的是,现代 CPU 会等待 RAM,而像特定操作码类型这样的项目很少能获得性能提升;与使用 SIMD、定点/整数等技术转变相反。

© www.soinside.com 2019 - 2024. All rights reserved.