有没有办法用 AVX2 编写 _mm256_shldi_epi8(a,b,1) ? (向量之间每 8 位元素移位一位)

Posted

技术标签:

【中文标题】有没有办法用 AVX2 编写 _mm256_shldi_epi8(a,b,1) ? (向量之间每 8 位元素移位一位)【英文标题】:Is there a way to write _mm256_shldi_epi8(a,b,1) with AVX2? (Shift one bit per 8-bit element between vectors) 【发布时间】:2018-07-23 09:52:16 【问题描述】:

我需要将b 的每个元素的最高位移动到a 的相应元素的底部,例如AVX512VBMI2 _mm256_shldi_epi16/32/64,计数为1

有人知道如何改变这种方式吗?

例子:

__m256i x =  11001100, 00110011, 11001100, 00110011,... x16 
__m256i y =  10111100, 10001011, 11000010, 01100111,... x16 
__m256i res = _mm256_shldi_epi16(x,y);

那么 res 包含:

10011001, 01100111, 10011001, 01100110, ...x16

(编者注:之前的问题描述为_mm256_sllv_epi8sllv 是一个可变计数移位,其中每个元素的计数来自另一个源中的相应元素,与双移位完全不同.)

【问题讨论】:

shift by one 案例有一个解决方法 【参考方案1】:

显然任务是将a的字节左移1,同时从b中的相应字节移入最高位,就像一个固定距离为1的微小漏斗移位。左移可以是完成一个字节添加,然后从b复制该位:

__m256i funnel_left1_epi8(__m256i a, __m256i b) 
    __m256i a2 = _mm256_add_epi8(a, a);
    __m256i bit_from_b = _mm256_and_si256(_mm256_srli_epi16(b, 7), _mm256_set1_epi8(1));
    return _mm256_or_si256(a2, bit_from_b);

【讨论】:

以上是关于有没有办法用 AVX2 编写 _mm256_shldi_epi8(a,b,1) ? (向量之间每 8 位元素移位一位)的主要内容,如果未能解决你的问题,请参考以下文章

用 AVX2 有条件地选择一个常数值

AVX2 1x mm256i 32bit 到 2x mm256i 64bit

在AVX2中重现_mm256_sllv_epi16和_mm256_sllv_epi8

如何处理 SIGSEGV,Segmentation fault。使用 Avx2 时

两个 16 位整数向量与 C++ 中的 AVX2 的内积

AVX2:U8绝对差