【发布时间】:2020-05-19 08:28:45
【问题描述】:
为了速度,我想读取第 9 个寄存器中的值引用的 8 个寄存器之一。 我看到的最快方法是使用 3 个条件跳转(检查第 9 位中的 3 位 登记)。这应该比使用偏移执行此操作的标准方法具有更短的延迟 内存读取,但这仍然需要至少 6 个时钟周期(至少一个测试加一个 有条件的 jmp 每比特检查)。
是否有任何商业 CPU(最好是 x86/x64)具有执行此“偏移寄存器”的内在功能 读取”只有一个时钟周期的延迟?
理论上,优化的 CPU 可以通过一次加法和一次移动来完成此操作,因此需要两个或一个时钟 周期似乎很容易......是否存在架构不关心超速的一般原因 为一个小数组增加一个偏移读取?
【问题讨论】:
-
如今将 CPU 寄存器视为一个数组确实不是一种常见的方法。我知道的最后一个允许这样做的架构是 PDP11,它在 80 年代后期消失了。为什么不像其他数组一样将数组放入某个内存位置?
-
通过变量索引访问寄存器或多或少会破坏寄存器重命名,因此对于快速处理器来说这是一个非常不可能的功能。您可以使用 VPERMD 对 YMM 寄存器进行某种索引,也许这对于您的用例来说仍然可以?
-
@fuz AVR 也可以做到这一点;寄存器被映射到地址空间。
-
CPU 没有 intriniscs;编译器具有内在函数。也许您的意思是“机器指令”或“寻址模式”(编译器可能具有内在的)?正如之前的评论者所说,大多数 ISA 不能使用运行时索引来索引寄存器,只能使用嵌入在指令机器代码中的索引。 (所以寄存器获取可以在解码后的任何时间发生,而不需要任何额外的间接作为 ISA 的一部分。)
-
自我修改代码比仅仅从数据缓存中刷新一行要昂贵得多;在现代 x86 上,它会刷新整个管道(性能计数器事件
machine_clears.smc)。如果你 JIT 一次并运行多次,那很好,如果你每次都这样做,那就是垃圾。在现代 Intel 上,存储转发延迟只有大约 3 到 5 个周期,类似于 4 或 5 个周期的 L1d 负载使用延迟。在需要低延迟数组索引的地方,您试图解决的更大问题是什么?你可以用 AVX2 shuffle 来解决它吗?这是 3c 延迟(加上来自整数 regs 的索引的vmovd更多)
标签: performance assembly x86 cpu-architecture intrinsics