AVX2移位(16位)整数

时间:2015-02-22 23:25:08

标签: x86 sse simd avx avx2

是否有内置指令对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位元素上运行良好。我问,因为性能(运行时间)对我来说至关重要。

1 个答案:

答案 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位,则需要额外排列原始值并屏蔽掉不需要的位