是否有内置指令对AVX2中的(16位)整数元素执行左右移位操作?
如以下示例所示:
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] --> [16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
和
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] --> [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
_mm_srli_si128(H,14)
和_mm_slli_si128(H,2)
在SSE3 16位元素上运行良好。我问,因为性能(运行时间)对我来说至关重要。
答案 0 :(得分:1)
不幸的是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位,则需要额外排列原始值并屏蔽掉不需要的位