我有两个SSE寄存器,我想用另一个的低半部分替换高半部分。像往常一样,最快的方式。
我想通过将其中一个寄存器移位8个字节然后alignr
来连接它是可行的。
是否有任何单指令解决方案?
答案 0 :(得分:4)
您可以使用punpcklqdq
将两个寄存器的低半部分组合成单个寄存器中的hi:lo。这与movlhps
FP指令的作用相同,也与unpcklpd
相同,但在CPU关注FP与整数shuffle的旁路延迟的整数域中运行。
额外阅读:合并两个寄存器的不同部分
palignr
只会将hi:xxx
与xxx: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指令表,可用于寄存器内或寄存器之间的各种数据移动。请参阅sse标记维基以获取链接,下载PDF,阅读第13.7节和第34页;置换数据"在第130页。
要将FP shuffle与内在函数一起使用,您必须使用_mm_castsi128_ps
和_mm_castps_si128
来混淆代码,这些代码是不会发出指令的重新解释。