英特尔向量指令将包装在32位int中的8个4位值零扩展到__m256i吗?

时间:2019-03-10 03:00:31

标签: sse avx avx2

如问题所示,

我有一个普通的int,它是8个打包的值,每个值4位,并且我想将其零扩展到256位向量寄存器中。 sse / avx / avx2有可能吗?

1 个答案:

答案 0 :(得分:2)

以下是应该保持顺序的解决方案:

__m256i foo(int x) {
    __m128i input = _mm_cvtsi32_si128(x);
    __m128i even  = input;
    // move odd nibbles to even positions:
    __m128i odd   = _mm_srli_epi32(input,4);
    // interleave: (only lower 64bit are used)
    __m128i inter = _mm_unpacklo_epi8(even, odd);
    // mask out wrong nibbles:
    __m128i masked = _mm_and_si128(inter, _mm_set1_epi32(0x0f0f0f0f));
    // convert to 32bit:
    return _mm256_cvtepu8_epi32(masked);
}

Godbolt链接:https://godbolt.org/z/8RLUVE

如果同时加载两个或四个int32来进行偶数和奇数半字节的交织和屏蔽,则效率可能会稍微提高。 (当然,这将导致多个__m256i向量)