不幸的是,AVX2 中没有这样的说明。所有 AVX2 指令都将 SSE2 扩展到 256 位,同时在 128 位 SSE2 中使用时要记住兼容性。
如果您知道在编译时要移位的 16 位整数的数量,则可以使用置换和移位的组合。例如,您可以在逻辑上将值分解为 64 位块,对这些块进行置换和移位,然后将其组合起来。
这就是我在代码中执行此操作的方式
static __m256i m256_srl16_1(__m256i i) {
// suppose i is [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
//[4, 3, 2, 1, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5]
__m256i srl64_q = _mm256_permute4x64_epi64(i, _MM_SHUFFLE(0,3,2,1));
//[ 1, 0, 0, 0 13, 0, 0, 0 9, 0, 0, 0 5, 0, 0, 0]
__m256i srl64_m = _mm256_slli_epi64(srl64_q, 3*16);
//[ 0, 16, 15, 14, 0, 12, 11, 10, 0, 8, 7, 6, 0, 4, 3, 2]
__m256i srl16_z = _mm256_srli_epi64(i, 1*16);
__m256i srl64 = _mm256_and_si256(srl64_m, _mm256_set_epi64x(0, ~0, ~0, ~0));
__m256i r = _mm256_or_si256(srl64, srl16_z);
return r;
}
如果您需要移动超过 64 位,则需要对原始值进行额外排列并屏蔽掉不需要的位