根据掩码合并位序列a和b

Merge bit sequences a and b according to a mask

根据bit twiddling hacks网站,操作

unsigned int a;    // value to merge in non-masked bits
unsigned int b;    // value to merge in masked bits
unsigned int mask; // 1 where bits from b should be selected; 0 where from a.
unsigned int r;    // result of (a & ~mask) | (b & mask) goes here

r = a ^ ((a ^ b) & mask); 

允许根据掩码合并两个位序列ab。我在想:

  1. 此操作是否有 specific/usual 名称?
  2. 在某些指令集上是否存在针对此操作的特定汇编指令?

我将其称为位混合,使用掩码异或方法。相关: 详细解释 how/why 那些布尔运算实现了这一点。

在SSE/AVX编程中,根据掩码从一个向量选择性地复制到另一个向量称为混合。 SSE4.1 在两个向量上添加了像 PBLENDVB xmm1, xmm2/m128, <XMM0>, where the implicit operand XMM0 controls which bytes of the src overwrite corresponding bytes in the dst. (Without SSE4.1, you'd usually AND and ANDNOT 掩码这样的指令,并将它们放在一起; masked-xor 技巧具有较少的指令级并行性,并且可能至少需要与 OR 方法一样多的 MOV 指令来复制寄存器。)

还有一个立即数混合指令,pblendw,其中掩码是一个 8 位立即数而不是寄存器。并且有 32 位和 64 位立即混合(blendpsblendpdvpblendd)和变量混合(blendvpsblendvpd)。

IDK 如果其他 SIMD 指令集(NEON、AltiVec、无论 MIPS 称之为什么,等等)是否也称它们为“混合”。


SSE/AVX(或 x86 整数指令)没有提供比通常的按位 XOR/AND 更好的东西来做 按位(而不是按元素) 混合直到 AVX512F。

AVX512F 可以使用单个 vpternlogdvpternlogq 指令 执行此(或任何其他按位三元函数)的按位版本. (d 和 q 元素大小之间的唯一区别是,如果您使用掩码寄存器进行合并掩码或对目标进行零掩码,但这并没有阻止英特尔即使在无掩码情况下也制作单独的内在函数:

__m512i _mm512_ternarylogic_epi32 (__m512i a, __m512i b, __m512i c, int imm8) 和等效的 ..._epi64 版本。

imm8立即字节为真值table。目的地的每一位都是独立确定的,来自 a、b 和 c 的相应位,通过将它们用作真值的 3 位索引 table。即 imm8[a:b:c].

当 AVX512 最终出现在主流 desktop/laptop CPU 中时,玩起来会很有趣,但这可能还需要几年时间。