1

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

4

1 回答 1

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

于 2017-04-12T09:25:28.057 回答