【发布时间】:2024-01-06 22:18:01
【问题描述】:
AVX2 有很多好东西。例如,它有很多指令,这些指令比它们的前身要强大得多。以VPERMD 为例:它允许您完全任意地从一个 256 位长的 32 位值向量广播/洗牌/置换到另一个,并在运行时选择置换1。从功能上讲,这淘汰了一大堆现有的旧解包、广播、置换、随机播放和移位指令3。
酷豆。
那么VPERMB 在哪里?即,相同的指令,但在字节大小的元素上工作。或者,就此而言,对于 16 位元素,VPERMW 在哪里?在涉足 x86 汇编一段时间后,很明显 SSE PSHUFB 指令几乎是有史以来最有用的指令之一。它可以进行任何可能的排列、广播或逐字节洗牌。此外,它还可用于进行 16 次并行 4 位 -> 8 位表查找2。
不幸的是,PSHUFB 在 AVX2 中没有扩展到跨车道,因此它仅限于车道内行为。 VPERM 指令可以进行交叉洗牌(实际上,“perm”和“shuf”似乎是指令助记符中的同义词?)——但省略了 8 位和 16 位版本?
似乎甚至没有模拟此指令的好方法,而您可以轻松地用较小宽度的随机播放来模拟较大宽度的随机播放(通常,它甚至是免费的:您只需要不同的掩码)。
我毫不怀疑英特尔知道PSHUFB 的广泛使用和大量使用,所以自然会产生一个问题,为什么在 AVX2 中省略了字节变体。该操作本质上是否更难在硬件中实现?是否存在强制省略的编码限制?
1在运行时可选择,我的意思是定义洗牌行为的掩码来自寄存器。这使得指令比采用立即 shuffle 掩码的早期变体更灵活一个数量级,就像 add 比 inc 更灵活,或者变量移位比立即移位更灵活。
2或 AVX2 中的 32 个此类查找。
3如果旧指令的编码较短,或者避免从内存中加载掩码,则旧指令有时会很有用,但在功能上它们已被取代。
【问题讨论】:
-
s/babble/dabble/?此外,“在运行时可选择”的一个好术语是“可变随机播放”。变量移位指令(如
vpsrlvd)已经使用了这个术语。 -
是的,dabble,虽然 babble 有时也很有意义。我不确定“变量”。我认为这种转变几乎与“是否立即”的问题是正交的。问题是你不能为不同的向量元素发出不同的班次计数。有点像 if vector
add只允许向所有元素添加单个值。这与参数是否只能指定为立即不同。当然,这种转变有点特别,因为大多数人甚至没有这个问题,这就是我对英特尔所说的“变量”的印象。 -
哦,好点,您已经可以在 xmm reg 的 low64 中获得所有元素的移位计数。我仍然认为“变量洗牌”在没有解释的情况下立即显而易见,考虑到一些上下文。
-
顺便说一句,你可以用大约 11 条指令(13 微指令)模拟
vpermi2b。如果您可以预处理要多次使用的置换向量,这将减少到 5 条指令(7 微秒)。
标签: assembly x86 intel sse avx2