2016-08-05 32 views
2

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

我估计是由8个字节移位寄存器中的一个,然后alignr来连接是可行的。

有没有单一指令的解决方案?在单个寄存器LO:

+2

'movlhps',不知道绕行延误,虽然 – harold

+0

@harold谢谢,我可以试试。 –

+0

@Harold:mh,我被卡住了,因为我使用的是intrisincs语法,而我的数据是整数。演员是不可能的。 –

回答

4

可以使用punpcklqdq到两个寄存器的低半组合成喜。这与movlhps FP指令所执行的操作相同,也与unpcklpd相同,但在处理旁路延迟的FP与整数混洗的CPU上的整数域中运行。


加成读数:两个寄存器

palignr组合不同的部件只会有利于与xxx:lo组合hi:xxx,以产生lo:hi(即相反的)。您可以使用FP洗牌(的movsd的寄存器登记表),以获得hi:lo(通过移动xxx:lo低一半更换低垃圾hi:xxx)。如果没有这一点,你想使用punpckhqdq将一个寄存器的高一半带到低一半,然后使用punpcklqdq来组合两个寄存器的低一半。

在比Intel的Nehalem其他大多数的CPU,对整数数据浮点混洗通常是细(小或矢量整数ALU指令之间使用时没有额外延时)。在Nehalem上,你可能会有两个额外的延迟周期进入和退出浮点洗牌(总共4个周期的延迟),但如果它是循环运行的依赖链的一部分,这对吞吐量来说只是一个大问题。有关更多信息,请参阅Agner Fog's guides

昂纳的优化组件引导件还具有是用于内或寄存器之间的各种数据的移动有用SSE/AVX指令表的整个部分。请参阅标记wiki以获取链接。

要使用带有内在函数的FP洗牌,必须用_mm_castsi128_ps_mm_castps_si128来排除代码,这些代码是不发出指令的重新解释。

+3

看来,PUNPCKLQDQ正是我所需要的:Destination [0..63] = Destination [0..63]; \t \t目的地[64..127] =来源[0..63]; –

+1

@YvesDaoust:固定以正确回答问题:P –