AVX2 中的条件指令

Conditional instructions in AVX2

您能否提供 AVX2 中可用的条件指令列表? 到目前为止,我发现了以下内容:

有条件乘法、条件加法等吗?

此外,如果采用 imm8 的指令计数(如 _mm256_blend_*),您能否解释一下如何在向量比较后获得 imm8

英特尔内在指南建议使用掩码进行收集、加载和存储操作。 blend_epi16 中的立即数 imm8 是不可编程的,除非自修改代码或跳转 table 被认为是一个选项。仍然可以使用来自 BMI2 的 pext 来从 movemask 的结果中压缩奇数定位位的一半——一个人从 AVX2 中的 movemask 获得 32 个独立的掩码位,但是 blend_epi16 使用每个位来控制四个字节——或者每组一个 16 位变量。

AVX512 为几乎所有指令引入了可选的零屏蔽和合并屏蔽。

在此之前,要进行条件加法,请屏蔽一个操作数(使用 vandpsvandnps 作为逆运算) 加法之前(而不是vblendvps 在结果上)。这就是打包比较 instructions/intrinsics 产生全零或全一元素的原因。

0.0 是附加标识元素,因此添加它是一个空操作。 (除了 -0.0 和 +0.0 的 IEEE 语义,我忘记了它是如何工作的)。

屏蔽常量输入而不是混合结果可以避免使关键路径变长,例如有条件地添加 1.0.


条件乘法比较麻烦,因为0.0不是乘法恒等式。您需要乘以 1.0 以保持值不变,并且您无法通过比较结果使用 AND 或 ANDN 轻松生成该值。您可以混合一个输入,或者您可以对输出进行乘法和混合。

blendv 的替代方案是至少 3 个布尔值,例如 AND/ANDN/OR,但这通常不值得。尽管请注意 Haswell 运行s vblendvpsvpblendvb 作为端口 5 的 2 微指令,因此与使用可以在任何端口上 运行 的整数布尔值相比,这是一个潜在的瓶颈。 Skylake 运行 将它们 vblendvps 作为任何端口的 2 微码。不过,采取措施避免在关键路径上出现 blendv 可能是有意义的。

屏蔽输入操作数或混合结果通常是您执行无分支 SIMD 条件语句的方式。

BLENDV 通常至少为 2 微指令,因此它比 AND 慢。

立即混合效率更高,但您不能使用它们,因为imm8 混合控制必须是一个编译时常量 嵌入到指令的机器码。这就是 immediate 在汇编语言上下文中的意思。