如何交换256位AVX(YMM)寄存器中的低128位和高128位
我正在移植 SSE SIMD 代码以使用 256 位 AVX 扩展,但似乎找不到任何可以混合/洗牌/移动高 128 位和低 128 位的指令。
背景故事:
我真正想要的是 VHADDPS
/_mm256_hadd_ps
表现得像 HADDPS
/_mm_hadd_ps
,只有 256比特的话。不幸的是,它就像对 HADDPS
的两次调用,独立作用于低位字和高位字。
I am porting SSE SIMD code to use the 256 bit AVX extensions and cannot seem to find any instruction that will blend/shuffle/move the high 128 bits and the low 128 bits.
The backing story:
What I really want is VHADDPS
/_mm256_hadd_ps
to act like HADDPS
/_mm_hadd_ps
, only with 256 bit words. Unfortunately, it acts like two calls to HADDPS
acting independently on the low and high words.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用 VPERM2F128,可以交换低 128 位和高 128 位(以及其他排列)。内在函数的用法看起来像
第三个参数是一个控制字,它为用户提供了很大的灵活性。有关详细信息,请参阅英特尔 Intrinsic 指南。
Using VPERM2F128, one can swap the low 128 and high 128 bits ( as well as other permutations). The instrinsic function usage looks like
The third argument is a control word which gives the user a lot of flexibility. See the Intel Instrinsic Guide for details.
阅读相关内容 此处。并且在线尝试!
注意:该指令需要AVX2(不仅仅是AVX1) )。
作为评论 @PeterCordes Zen2 / Zen3 CPU 上的速度 _mm256_permute2x128_si256(x, x, i) 是最好的选择,尽管与函数 _mm256_permute4x64_epi64(x, i) 有两个参数。
在 Zen1 和 KNL/KNM(以及推土机系列挖掘机)上,_mm256_permute4x64_epi64(x, i) 效率更高。在其他CPU(包括主流Intel)上,两种选择都是相同的。
正如已经说过的,
_mm256_permute2x128_si256(x, y, i)
和_mm256_permute4x64_epi64(x, i)
都需要AVX2,而_mm256_permute2f128_si256(x, i)
只需要 AVX1。Read about it here. And Try it online!
Note: This instruction needs AVX2 (not just AVX1).
As commented by @PeterCordes speed-wise on Zen2 / Zen3 CPUs _mm256_permute2x128_si256(x, x, i) is the best option, even though it has 3 arguments compared to function _mm256_permute4x64_epi64(x, i) suggested by me having 2 arguments.
On Zen1 and KNL/KNM (and Bulldozer-family Excavator), _mm256_permute4x64_epi64(x, i) suggested by me is more efficient. On other CPUs (including mainstream Intel), both choices are equal.
As already said both
_mm256_permute2x128_si256(x, y, i)
and_mm256_permute4x64_epi64(x, i)
need AVX2, while_mm256_permute2f128_si256(x, i)
needs just AVX1.据我所知,执行此操作的唯一方法是使用
_mm256_extractf128_si256
和_mm256_set_m128i
。例如,交换 256 位向量的两半:The only way that I know of doing this is with
_mm256_extractf128_si256
and_mm256_set_m128i
. E.g. to swap the two halves of a 256 bit vector: