在 x86-64 SIMD 指令名称以及可用于从 C/C++ 访问它们的 intrinsic 函数中,您可以找到术语 shuffle(例如,
_mm_shuffle_epi32
)和 permute(例如, _mm_permute_pd
)。
从表面上看,它们似乎都用于数据移动。有什么区别?
我没有在 x86 之外寻找灵感。 我认为这里没有任何标准约定。
我认为他们只是在 SSSE3 pshufb
和 AVX1
vpermilps/pd
/
vperm2f128
之间的某个时间点从“随机播放”切换到“排列”。 AVX 之前的所有内容都称为“shuffle”,之后的所有内容都称为“permute”。(SSE4.x没有引入任何名为“shuffle”或“permute”的指令,只是
pinsrd
/
pextrd
等操作数大小是SSE4.1添加的主要shuffle)
有 2 个例外,不包括 vshufps
、
vpshufd
等的 VEX / EVEX 编码:
AVX512F VSHUFF32X4
vshufps
具有相同的设计:目标的低半部分从第一个源选择元素,高半部分选择元素从第二个来源中选择。 例如_mm512_shuffle_i64x2(__m512i a, __m512i b, int imm);
此命名有助于记住随机播放控制的工作原理。 对于 4 个输出通道,只有 4 个 2 位选择器的空间,而不是 4 个 3 位选择器。 256 位操作数大小版本仍然具有相同的限制,因此它仅使用立即数的低 2 位,如 shufpd
。
AVX512BITALG VPSHUFBITQMB
vpmultishiftqb
(并行位域提取)+向量->掩码(如移动掩码)。 因此它可以选择输入的每个 qword 块中的任意 8 位。
AVX512 256 位粒度操作当前仅存在 VEXTRACTF32x8 和 VINSERTF32x8 等名称,而不是 shuf 或 perm。
_mm_permute_ps
imm8 或
_mm_permutevar_ps
__m128i 控制与 AVX2
vpermps
= _mm256_permutexvar_ps
;不可用于立即控制,但 vpermpd 可用。Intel 的内在函数指南仅列出了
_mm256_permutevar8x32_ps
的 AVX2 形式
vpermps
,而 ISA 参考手册仅列出了
permutexvar
。 (更新:哪些更高版本的内在函数指南将其列为 AVX-512;GCC 同意这一点,拒绝在未启用 AVX-512 的情况下编译它)。 不管怎样,奇怪的选择,8x32 听起来像 AVX512 指令(带有每个元素掩码)。 他们确实需要一种方法将其与 AVX1
vpermilps
区分开来,他们使用了明显的名称
_mm256_permute_ps
和
_mm256_permutevar_ps
。
我们可以轻松排除以下所有假设:
pshufd xmm, xmm/mem, imm
) 与就地随机播放(
pshufb data, idx
或
shufps xmm, xmm, imm
)
vpermilps
vs. AVX2
vpermps
)
pshufd
和
vpermq
-立即数中的工作方式相同。但与“棘手”的
vshuff32x4
情况不同,
pshufd
和
vpermq
的工作方式都很明显,因此无需与另一个助记符进行类比。 另外,“pshuf”与“shuf”或“perm”相比有点尴尬,所以我明白为什么他们想要其他东西来表示压缩整数。 请注意,“shuf”名称可以一直追溯到 SSE1
shufps
,由 Pentium III (Katmai) 与 MMX2
pshufw mm, mm, imm8
同时引入。P5 Pentium MMX 没有任何名为 shuf/perm 指令的指令,只有各种大小的
punpckl/h
shuffle。
https://nasm.us/doc/nasmdocb.html#section-B.1.7(NASM 附录很有帮助,因为它按介绍顺序将助记符分组。这就是让我注意到 vshuff32x4
助记符的原因在我以为他们已经把所有东西都称为“烫发”之后,就在 AVX512 的东西里了。)