【发布时间】:2013-07-10 17:54:17
【问题描述】:
是否有单个 SSE 指令将两个寄存器的高低字交错到另一个寄存器中?例如:
r[63-0] = a[64-127]
r[64-127] = b[63-0]
【问题讨论】:
标签: performance assembly x86 sse
是否有单个 SSE 指令将两个寄存器的高低字交错到另一个寄存器中?例如:
r[63-0] = a[64-127]
r[64-127] = b[63-0]
【问题讨论】:
标签: performance assembly x86 sse
不,因为没有具有两个来源和不同目的地的 SSE 洗牌。但是,如果r 与a 相同,则可以使用shufpd。如果需要保留a的值:
movapd r, a
shufpd r, b, 1
在最近的 µarches 中,movapd 是空闲的并在 rename[*] 中处理,因此从执行核心的角度来看,这实际上是一条“单指令”。
如果 AVX 可用,您可以使用vshufpd。
[*] 重命名的能力可能会饱和,在这种情况下,额外的 reg-reg 移动将表现得像正常的端口 0|1|5 操作——幸运的是,现实世界的代码几乎总是在其中一个上有一些气泡端口,因此移动往往仍然是“免费的”。
【讨论】:
mov 指令,即使通过重命名消除,也不一定是免费的——它们不占用执行端口,但它们仍然在 ROB 中占用一个条目并计数一个循环 4 个融合域 uops 的所有重要限制。考虑到最近 CPU 上的大量执行单元,没有长依赖链的设计良好的代码,尤其是标量代码,通常可以达到 4-uop 的限制,此时 mov 非常不免费。 AVX 通过引入 3 参数指令在一定程度上缓解了这一问题,目标寄存器与两个源寄存器分开。