在x86-64 SIMD指令名称以及可以用于从C / C ++访问它们的intrinsic函数中,您会找到两个术语 shuffle (例如{{ 1}})和置换(例如_mm_shuffle_epi32
)。
从表面上看,它们似乎都用于数据移动。有什么区别?
答案 0 :(得分:3)
我没有在x86之外寻找灵感。我认为这里没有任何标准约定。
我认为他们只是在SSSE3 pshufb
和AVX1 vpermilps/pd
/ vperm2f128
之间的某个时间点从“随机播放”切换为“置换” 。 AVX之前的所有内容都称为“随机播放”,之后的所有内容均称为“置换”。
(SSE4.x并未引入任何名为“随机播放”或“置换”的指令,只是pinsrd
/ pextrd
和其他操作数大小是SSE4.1添加的主要随机播放)>
有2种例外情况,其中不包括vshufps
,vpshufd
等的VEX / EVEX编码:
AVX512F VSHUFF32X4
(以及64x2和整数版本),具有直接控制功能的128位粒度通道混洗具有与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。
内在名称在改组与置换之间都与指令助记符匹配,但是当助记符拥有时,它会在“行车道”中省去,这也要求交叉通道版本不同。 (例如,AVX1 vpermilps
= _mm_permute_ps
imm8或_mm_permutevar_ps
__m128i控件与AVX2 vpermps
= _mm256_permutexvar_ps
;不可用于直接控制,但vpermpd可用。 >
Intel的内部函数指南仅针对_mm256_permutevar8x32_ps
列出了vpermps
,而ISA参考手册仅列出了permutexvar
。我假设大多数编译器都支持较旧的permutexvar
名称。无论如何,奇怪的选择是8x32听起来像是AVX512指令(带有逐元素屏蔽);也许就是这个新内在名称的来源。
我没有发现其他模式。 我们可以轻松排除以下所有假设:
pshufd xmm, xmm/mem, imm
)与就地随机播放(pshufb data, idx
或shufps xmm, xmm, imm
)vpermilps
与AVX2 vpermps
)随机控制立即在pshufd
和vpermq
中以相同的方式工作。但是与“棘手的” vshuff32x4
情况不同,pshufd
和vpermq
都以明显的方式工作,因此无需类推另一个助记符。另外,“ pshuf”与“ shuf”或“ perm”相比有点尴尬,因此我可以理解为什么他们想要打包整数。
请注意,“ shuf”名称一直追溯到由Pentium III(Katmai)与MMX2 shufps
同时引入的SSE1 pshufw mm, mm, imm8
。
P5 Pentium MMX没有名为shuf / perm指令的任何指令,只是各种大小的punpckl/h
随机播放。
https://nasm.us/doc/nasmdocb.html#section-B.1.7(NASM附录很有用,因为它按导入顺序将助记符分为几组。这就是让我注意到AVX512中vshuff32x4
助记符向下的原因,我以为它们已经切换了称一切为“烫发”。)