我有两个 SSE 寄存器,我想用另一个的低半部分替换一个的高半部分。像往常一样,最快的方法。
我想可以通过将其中一个寄存器移位 8 个字节,然后使用 alignr
连接来实现。
有没有单指令解决方案?
最佳答案
您可以使用punpcklqdq
将两个寄存器的低半部分合并到单个寄存器中的 hi:lo 中。这与 movlhps
FP 指令以及 unpcklpd
的功能相同,但在关心 FP 与旁路延迟的整数洗牌的 CPU 上的整数域中运行。
额外阅读:组合两个寄存器的不同部分
palignr
仅适用于将 hi:xxx
与 xxx:lo
组合,以生成 lo:hi
>(即反转)。您可以使用 FP shuffle(movsd
的寄存器-寄存器形式)来获取 hi:lo
(通过移动 xxx:lo
的下半部分) > 替换 hi:xxx
中的低垃圾)。如果没有它,您需要使用 punpckhqdq 来将一个寄存器的高半部分带到低半部分,然后使用 punpckhqdq 来组合两个寄存器的低半部分。
在除 Intel Nehalem 之外的大多数 CPU 上,整数数据上的浮点混洗通常都很好(在矢量整数 ALU 指令之间使用时,很少或没有额外的延迟)。在 Nehalem 上,您可能会在浮点洗牌中输入和输出两个周期的额外延迟(总共 4 个周期延迟),但如果它是循环承载依赖链的一部分,那么这对于吞吐量来说只是一个大问题。请参阅Agner Fog's guides了解更多信息。
Agner 的优化汇编指南还包含一整节 SSE/AVX 指令表,这些指令对于寄存器内或寄存器之间的各种数据移动很有用。请参阅sse标记 wiki 获取链接,下载 PDF,阅读第 130 页第 13.7 节“排列数据”。
要将 FP shuffle 与内在函数一起使用,您必须使用 _mm_castsi128_ps
和 _mm_castps_si128
来弄乱代码,它们是不发出指令的重新解释转换。
关于optimization - 如何连接两个SSE寄存器的低半部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38794487/