如何连接两个SSE寄存器的低半部分?

时间:2016-08-05 17:05:49

标签: optimization x86 sse simd

我有两个SSE寄存器,我想用另一个的低半部分替换高半部分。像往常一样,最快的方式。

我想通过将其中一个寄存器移位8个字节然后alignr来连接它是可行的。

是否有任何单指令解决方案?

1 个答案:

答案 0 :(得分:4)

您可以使用punpcklqdq将两个寄存器的低半部分组合成单个寄存器中的hi:lo。这与movlhps FP指令的作用相同,也与unpcklpd相同,但在CPU关注FP与整数shuffle的旁路延迟的整数域中运行。

额外阅读:合并两个寄存器的不同部分

palignr只会将hi:xxxxxx:lo合并,以产生lo:hi(即反转)。您可以使用FP shuffle(movsd的寄存器 - 寄存器形式)来获取hi:lo(通过移动xxx:lo的低半部分来替换hi:xxx中的低垃圾) 。如果没有这个,你想用punpckhqdq将一个寄存器的高半部分带到低半部分,然后用punpcklqdq组合两个寄存器的低半部分。

在Intel Nehalem以外的大多数CPU上,整数数据上的浮点混洗通常都很好(在向量整数ALU指令之间使用时很少或没有额外的延迟)。在Nehalem上,你可能会有两个循环的额外延迟进出浮点洗牌(总共4个周期的延迟),但这对于吞吐量来说只是一个很大的问题,如果它是a的一部分。循环携带的依赖链。有关详细信息,请参阅Agner Fog's guides

Agner的优化装配指南还有一整套SSE / AVX指令表,可用于寄存器内或寄存器之间的各种数据移动。请参阅标记维基以获取链接,下载PDF,阅读第13.7节和第34页;置换数据"在第130页。

要将FP shuffle与内在函数一起使用,您必须使用_mm_castsi128_ps_mm_castps_si128来混淆代码,这些代码是不会发出指令的重新解释。