有没有办法用 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)
我需要将 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_epi8
。sllv
是一个可变计数移位,其中每个元素的计数来自另一个源中的相应元素,并且是一点也不像双班制。)
显然任务是将 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);
}
我需要将 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_epi8
。sllv
是一个可变计数移位,其中每个元素的计数来自另一个源中的相应元素,并且是一点也不像双班制。)
显然任务是将 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);
}