shuffle 和 permute 有什么区别

What is the difference between shuffle and permute

在 x86-64 SIMD 指令名称以及可用于从 C/C++ 访问它们的 intrinsic 函数中,您可以找到术语 shuffle(例如,_mm_shuffle_epi32)和 permute(例如,_mm_permute_pd)。

从表面上看,它们似乎都用于数据移动。有什么区别?

我没有在 x86 之外寻找灵感。我认为这里没有任何标准约定。


我认为他们只是在某个时间点从 "shuffle" 切换到 "permute" 在 SSSE3 pshufb 和 AVX1 [=11= 之间] / vperm2f128。 AVX 之前的所有内容都称为 "shuffle",之后的所有内容都称为 "permute".

(SSE4.x 没有引入任何名为 "shuffle" 或 "permute" 的指令,只是 pinsrd / pextrd 和其他操作数大小是主要的洗牌SSE4.1 添加)


有 2 个例外,不包括 vshufpsvpshufd 等的 VEX / EVEX 编码:

AVX512F VSHUFF32X4(以及 64x2 和整数版本)具有即时控制的 128 位粒度通道洗牌 vshufps 具有相同的设计:来自第一个源的目标 selects 个元素,来自第二个源的高半 selects 个。例如_mm512_shuffle_i64x2(__m512i a, __m512i b, int imm); 此命名有助于记住随机播放控件的工作原理。 有 4 个输出通道,只有 4 个 2 位 select 或 4 个 3 位的空间。 256 位操作数大小版本仍然具有相同的限制,因此它仅使用立即数的低 2 位,例如 shufpd.

AVX512BITALG VPSHUFBITQMB is like vpmultishiftqb(并行位域提取)+ vector->mask(如移动掩码)。因此它可以 select 输入的每个 qword 块中的任意 8 位。

AVX512 256 位粒度操作目前仅存在名称如 VEXTRACTF32x8 和 VINSERTF32x8,而不是 shuf 或 perm。


就随机播放与置换而言,内在名称确实与指令助记符匹配,但如果助记符有,则可以省略 "in lane",要求交叉口版本也不同。 (例如 AVX1 vpermilps = _mm_permute_ps imm8 or _mm_permutevar_ps __m128i control vs. AVX2 vpermps = _mm256_permutexvar_ps;不能立即控制,但 vpermpd 是。

Intel 的内在函数指南仅列出 _mm256_permutevar8x32_ps for vpermps,而 ISA ref 手册仅列出 permutexvar。我假设大多数编译器都支持旧的 permutexvar 名称。无论如何,奇怪的选择,8x32 听起来像是一条 AVX512 指令(带有每个元素的屏蔽);也许这就是新内在名称的来源。


我没有注意到其他模式。 我们可以轻松排除以下所有假设:

  • 复制并随机播放 (pshufd xmm, xmm/mem, imm) 与就地随机播放 (pshufb data, idxshufps xmm, xmm, imm)
  • 直接控制与可变控制(pshufd 与 pshufb 或 AVX2 vpermd 与 vperm2i128)
  • 整数与 FP(SSE2 pshufd 与 shufps/pd;AVX2 vpermps 与 vpermd)
  • 1 源与 2 源(pshufd 与 shufps;AVX2 vpermd 与 AVX512 vpermt2d)
  • 车道交叉与车道内(AVX1 vpermilps 与 AVX2 vpermps

shuffle-control immediate 在 pshufdvpermq-immediate 中的工作方式相同。但与 "tricky" vshuff32x4 的情况不同,pshufdvpermq 都以显而易见的方式工作,因此无需与另一个助记符进行类比。此外,"pshuf" 与 "shuf" 或 "perm" 相比有点尴尬,所以我可以理解为什么他们想要其他东西来表示 packed-integer。

请注意,"shuf" 名称一直追溯到 SSE1 shufps,由 Pentium III (Katmai) 与 MMX2 pshufw mm, mm, imm8 同时推出。

P5 Pentium MMX 没有任何名为 shuf/perm 指令的指令,只有 punpckl/h 各种大小的随机播放。

https://nasm.us/doc/nasmdocb.html#section-B.1.7(那个 NASM 附录很有用,因为它按介绍顺序将助记符分组。这就是让我注意到 vshuff32x4 之后 AVX512 中的助记符的原因我以为他们会转而调用所有内容 "perm"。)