_mm_movemask_epi8 的内在逆

And*_* S. 3 c x86 sse simd sse4

首先我将描述该任务:

我需要:

  1. 比较两个__m128i
  2. 以某种方式对结果进行按位与某个uint16_t值(可能使用_mm_movemask_epi8先然后只是&)。
  3. 根据blend结果​​计算初始值。

所以问题是,正如您可能已经猜到的那样,混合接受__m128i作为掩模,而我将拥有uint16_t. 因此,我要么需要某种反向指令,_mm_movemask_epi8要么完全做其他事情。

有些观点——我可能无法将该uint16_t值更改为其他类型,这很复杂;我在 SSE4.2 上这样做,所以没有 AVX;这里有一个类似的问题How to Perform the inverse of _mm256_movemask_epi8 (VPMOVMSKB)? 但这是关于 avx 的,我对此非常缺乏经验,所以我无法采用该解决方案。

PS:我可能也需要为手臂做这件事,希望得到任何建议。

xiv*_*r77 6

当您_mm_movemask_epi8在向量比较(产生-1fortrue0for )之后执行此操作时false,您将获得一个 16 位整数(假设仅 SSE),其第nth设置为等于向量中的n第 th字节。-1

下面是逆(逆?)操作。

static inline __m128i bitMaskToByteMask16(int m) {
  __m128i sel = _mm_set1_epi64x(0x8040201008040201);
  return _mm_cmpeq_epi8(
    _mm_and_si128(
      _mm_shuffle_epi8(_mm_cvtsi32_si128(m),
        _mm_set_epi64x(0x0101010101010101, 0)),
      sel),
    sel);
}
Run Code Online (Sandbox Code Playgroud)

请注意,您可能希望使用从整数掩码转换而来的向量掩码执行按位运算,而无需在整数操作和向量操作之间来回切换。