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

标签 optimization x86 sse simd

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

我想可以通过将其中一个寄存器移位 8 个字节,然后使用 alignr 连接来实现。

有没有单指令解决方案?

最佳答案

您可以使用punpcklqdq将两个寄存器的低半部分合并到单个寄存器中的 hi:lo 中。这与 movlhps FP 指令以及 unpcklpd 的功能相同,但在关心 FP 与旁路延迟的整数洗牌的 CPU 上的整数域中运行。


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

palignr 仅适用于将 hi:xxxxxx: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 指令表,这些指令对于寄存器内或寄存器之间的各种数据移动很有用。请参阅标记 wiki 获取链接,下载 PDF,阅读第 130 页第 13.7 节“排列数据”。

要将 FP shuffle 与内在函数一起使用,您必须使用 _mm_castsi128_ps_mm_castps_si128 来弄乱代码,它们是不发出指令的重新解释转换。

关于optimization - 如何连接两个SSE寄存器的低半部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38794487/

相关文章:

c++ - 在 Clang 下解决缺少 Yz 机器约束的问题?

c - SSE int vs. float 练习

performance - 为什么部署的 Meteor 站点需要这么长时间才能加载?

MySQL ...根据查询另一个表从表中删除记录

python - 将步长添加到线性优化中

python - 优化社交排行榜

c++ - 在 32 位 Linux 内核上使用 C++ 在堆上分配超过 2GB

compiler-construction - 为 x86 处理器生成程序集

c++ - (Visual) C++ 中动态创建函数的调用约定

c++ - g++ 4.2 SSE 指令的内联汇编用对齐的 XMM 寄存器拷贝包装用户汇编代码