我有一个普通的int,它是8个打包的值,每个值4位,并且我想将其零扩展到256位向量寄存器中。 sse / avx / avx2有可能吗?
答案 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
向量)