0

是否有一个或两个用于在 XMM 寄存器之间交换值的 x86 指令;类似于 XCHG 指令?不能使用内存、临时寄存器或 XOR 副本。

4

3 回答 3

1

这是算术交换的完全未经测试的代码:

vpsubd xmm0, xmm1
vpaddd xmm1, xmm0
vpsubd xmm0, xmm1, xmm0

与 xor 不同,减法不是可交换的,因此您最终会遇到不幸的最后一行,如果没有 avx,您将无法真正做到(嗯,您可以,但是使用暂存器,然后最好使用移动)。

在大多数处理器上使用暂存寄存器会更快(我想 P4 除外,但没人关心 P4,对吧?)。在较旧的处理器上,因为前两个移动可以并行执行,在最新的处理器上,因为它们在前端处理 xmm reg-reg 移动,使用寄存器重命名。寄存器重命名和纯粹用重命名处理指令都不是新技巧,重命名自 Pentium Pro 以来就一直在使用,并且fxch通常使用重命名来实现。使用寄存器重命名实现 xmm reg-reg 移动是一个相当新的技巧,它在 Ivy Bridge、Haswell、Bulldozer 和 Piledriver 中使用。

通常,您可以通过将循环展开 2 来摆脱循环中的交换。不在循环中的交换很少需要,甚至更不会成为瓶颈。

于 2013-06-18T14:10:26.817 回答
1

xchg操作的真正价值在于它在同步原语、自旋锁等中的使用。由于其隐含的lock前缀,它可能会造成严重的惩罚。当然没有人会使用 SSE 实现同步原语,但交换有什么优点吗?有时它可能有用,但是在 32 位模式下有 8 个 SSE 寄存器,在 64 位模式下有 16 个,为什么不简单地使用 SSE 暂存寄存器呢?我不知道是否有任何 x86-64 处理器在其 SIMD 单元中使用寄存器重命名等(以消除错误的依赖关系)。

您已经排除了使用xorps(或_mm_xor_ps内在),这在现代处理器上通常是一个无用的技巧 - 当然是通用寄存器,并且您已经排除了内存的使用。恐怕你所有的可能性都用尽了。总结:没有。

于 2013-06-18T11:26:43.333 回答
1

使用PXOR指令是在 XMM 寄存器之间交换内容的最短、最快的方式。此代码在 xmm0 和 xmm1 之间交换内容。

  pxor  xmm0, xmm1
  pxor  xmm1, xmm0
  pxor  xmm0, xmm1

那么,哪里可以看出问题呢?

于 2013-06-18T13:45:12.767 回答