首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >_mm256_packs_epi32,但按顺序打包除外

_mm256_packs_epi32,但按顺序打包除外
EN

Stack Overflow用户
提问于 2021-06-15 01:58:26
回答 1查看 230关注 0票数 1

我们可以使用_mm256_packs_epi32。如下:__m256i e = _mm256_packs_epi32 ( ai, bi);

在调试器中,我看到ai:m256i_i32 = {0, 1, 0, 1, 1, 1, 0, 1}的值。我还看到bi:m256i_i32 = {1, 1, 1, 1, 0, 0, 0, 1}的值。包装给了我e:m256i_i16 = {0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1}。包装是交错的。所以我们有前四个数字在ai中,前四个数字在bi中,最后四个数字在ai中,最后四个数字在bi中按这个顺序排列。

我想知道是否有这样一种指令,就是将ai和bi并排打包,而不需要交织。

包装后的vpermq是可行的,但我想知道是否有一个单一的指令来实现这一点。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-15 08:28:50

不幸的是,在AVX-512之前没有顺序交叉车道打包。(即使这样,也只适用于一个寄存器,或者没有饱和。)

vpacksswdvpalignr这样的混搭在车道上的行为是AVX2的主要缺点之一,这使得这些洗牌的256位版本不如它们的__m128i版本有用。但是在英特尔和Zen2 CPU上,如果您需要按特定顺序使用__m256i向量,在最后使用vpermq是最好的。(或在2级包装后带有向量常数的vpermdt)?)

如果您的32位元素来自于解压更窄的元素,而您不关心更宽元素的顺序,那么您可以使用车道内解包扩展,这使您可以重新打包到原来的顺序中。

这对于零扩展解包来说很便宜:_mm256_unpacklo/hi_epi16 (带有_mm256_setzero_si256())。这和vpmovzxwd (_mm256_cvtepu16_epi32)一样便宜,而且实际上更好,因为您可以对源数据执行256位的加载,并以两种方式解压缩,而不是只在输入寄存器底部的数据上工作的vpmovzx...。(而且内存源vpmovzx... ymm, [mem]不能在英特尔CPU上将负载与YMM目标进行微融合,只用于128位XMM版本,因此前端成本与单独的加载和洗牌指令相同。)

但是,对于需要签名扩展的数据,这个技巧不太管用。vpcmpgtw得到高一半的vpunpckl/hwd确实有效,但是vpermq在重新包装时也是一样好的,只是不同的执行端口压力。所以vpmovsxwd在那里更简单。

将数据分割成奇数/偶数(而不是低/高)也可以工作,例如将16位元素零扩展为32位元素:

代码语言:javascript
运行
复制
   auto  veven  = _mm256_and_si256(v, _mm256_set1_epi32(0x0000FFFF));
   auto  vodd   = _mm256_srli_epi32(v, 16);

经过处理后,可以与shift和vpblendw进行重组。(英特尔Skylake /冰湖5号端口1 uop )。或者是字节,使用控制向量的vpblendvb,但这在Intel上要花费2个uop (但任何端口除外),而在Zen2上只需1uop。(这些uop计数不包括将奇数元素与其起点对齐的vpslld ymm, ymm, 16移位。)

,即使使用AVX-512,情况也不是很好。仍然可以使用单个洗牌uop将两个向量组合到相同宽度的一个。

对于任何一对元素大小,如vpmovzx / sx的逆值,都有非常好的单矢量截断或符号或无符号饱和的缩小。例如vpmov[su]qb,有一个可选的内存目的地。

(有趣的事实:vpmovdm [rdi]{k1}, zmm0是Xeon (缺乏AVX-512 be和AVX-512 in )对内存进行字节屏蔽存储的唯一方法;这可能就是这些存储以内存目的地形式存在的原因。在像Skylake-X /Skylake这样的主流英特尔上,内存目的地版本并不比单独打包到寄存器中存储更便宜。https://uops.info/)

AVX-512也有一个很好的2输入洗牌和一个控制向量,所以对于dword到word截断您可以使用vpermt2w zmm1, zmm2, zmm3。但这需要一个洗牌控制向量,而vpermt2w是SKX和IceLake上的3 uop。(t2dt2q为1 uop)。vpermt2b只在AVX-512VBMI (冰湖)提供,在那里也有3个uops。

(不像vpermb在冰湖上是1 uop,而AVX-512 is vpermw冰湖上还有2英尺。因此,它们没有降低向后兼容指令的前端成本,但ICL可以在端口0或1上运行它的2个uop中的一个,而不是在端口5上的洗牌单元上运行两个uop。也许ICL有一个uop将洗牌控件预处理成vpermb控件或什么的,这也可以解释为什么延迟会有所改善:数据的3个周期->数据,控制>数据的4个周期->数据。对于2p5 uops,SKX上有6个周期,显然是从控件和数据向量开始的串行依赖。)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67979078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档