是否有一个或两个用于在 XMM 寄存器之间交换值的 x86 指令;类似于 XCHG 指令?不能使用内存、临时寄存器或 XOR 副本。
3 回答
这是算术交换的完全未经测试的代码:
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 来摆脱循环中的交换。不在循环中的交换很少需要,甚至更不会成为瓶颈。
该xchg
操作的真正价值在于它在同步原语、自旋锁等中的使用。由于其隐含的lock
前缀,它可能会造成严重的惩罚。当然没有人会使用 SSE 实现同步原语,但交换有什么优点吗?有时它可能有用,但是在 32 位模式下有 8 个 SSE 寄存器,在 64 位模式下有 16 个,为什么不简单地使用 SSE 暂存寄存器呢?我不知道是否有任何 x86-64 处理器在其 SIMD 单元中使用寄存器重命名等(以消除错误的依赖关系)。
您已经排除了使用xorps
(或_mm_xor_ps
内在),这在现代处理器上通常是一个无用的技巧 - 当然是通用寄存器,并且您已经排除了内存的使用。恐怕你所有的可能性都用尽了。总结:没有。
使用PXOR
指令是在 XMM 寄存器之间交换内容的最短、最快的方式。此代码在 xmm0 和 xmm1 之间交换内容。
pxor xmm0, xmm1
pxor xmm1, xmm0
pxor xmm0, xmm1
那么,哪里可以看出问题呢?