如何连接两个 SSE 寄存器的低半部分?
Posted
技术标签:
【中文标题】如何连接两个 SSE 寄存器的低半部分?【英文标题】:How to concatenate the low halves of two SSE registers? 【发布时间】:2016-08-05 17:05:48 【问题描述】:我有两个 SSE 寄存器,我想将一个的高半部分替换为另一个的低半部分。像往常一样,最快的方式。
我想可以通过将其中一个寄存器移动 8 个字节,然后将 alignr
连接起来。
有没有单指令解决方案?
【问题讨论】:
movlhps
,但不确定绕过延迟
@harold 谢谢,我可以试试。
@Harold:嗯,我被卡住了,因为我使用的是 intrisincs 语法并且我的数据是整数。无法进行投射。
是的,它们是:_mm_castsi128_ps
和 _mm_castps_si128
是不发出指令的重新解释转换。
【参考方案1】:
您可以使用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
将一个寄存器的高半部分带到低半部分,然后使用punpcklqdq
组合两个寄存器的低半部分。
在除 Intel Nehalem 之外的大多数 CPU 上,整数数据上的浮点混洗通常都很好(在向量整数 ALU 指令之间使用时几乎没有或没有额外延迟)。在 Nehalem 上,您可能会在浮点 shuffle 进出两个周期的额外延迟(总共有 4 个周期的延迟),但如果它是循环承载的依赖链的一部分,这只是吞吐量的一个大问题。请参阅Agner Fog's guides 了解更多信息。
Agner 的 Optimizing Assembly 指南还包含一整节 SSE/AVX 指令表,这些指令对寄存器内或寄存器之间的各种数据移动很有用。请参阅sse 标签 wiki 获取链接,下载 PDF,阅读第 130 页的第 13.7 节“置换数据”。
要将 FP shuffle 与内在函数一起使用,您必须使用 _mm_castsi128_ps
和 _mm_castps_si128
将代码弄乱,它们是不发出指令的重新解释转换。
【讨论】:
看来 PUNPCKLQDQ 完全符合我的需要:Destination[0..63] = Destination[0..63];目的地[64..127] = 源[0..63]; @YvesDaoust:已修复以正确回答问题:P以上是关于如何连接两个 SSE 寄存器的低半部分?的主要内容,如果未能解决你的问题,请参考以下文章