提问人:Steffen Roeber 提问时间:9/21/2023 最后编辑:Steffen Roeber 更新时间:9/26/2023 访问量:83
如何使用_mm256_shuffle_epi8对元素进行排序
How to use _mm256_shuffle_epi8 to order elements
问:
我尝试以下代码。我知道随机播放功能中有一些车道限制。但我不知道如何正确处理它。有人有想法吗?
#include <immintrin.h>
int main() {
auto vals = _mm256_setr_epi8(
0, 3, 6, 9,
1, 4, 7, 10,
2, 5, 8, 11,
0, 0, 0, 0,
12, 15, 18, 21,
13, 16, 19, 22,
14, 17, 20, 23,
0, 0, 0, 0
);
auto mask = _mm256_setr_epi8(
0, 4, 8,
1, 5, 9,
2, 6, 10,
3, 7, 11,
16, 20, 24,
17, 21, 25,
18, 22, 26,
19, 23, 27,
-1, -1, -1,
-1, -1, -1,
-1, -1);
auto res = _mm256_shuffle_epi8(vals, mask);
/*res is:
0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3 12 17 18 19 20 21 22 23 0 0 0 0 0 0 0 0 0
but should
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 0 0 0 0 0 0 0 0 0
*/
return 0;
}
答:
2赞
Soonts
9/26/2023
#1
问题是,不能在向量的 16 字节通道之间移动这些字节。_mm256_shuffle_epi8
一种可能的解决方法是之后的另一个随机指令,这里有一个例子。
__m256i collectRgb( __m256i vals )
{
// Move the bytes within 16-byte pieces of the vector
const __m128i gather16 = _mm_setr_epi8(
0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, -1, -1, -1, -1 );
const __m256i gatherMask = _mm256_broadcastsi128_si256( gather16 );
vals = _mm256_shuffle_epi8( vals, gatherMask );
// Shuffle 4-byte pieces across the complete AVX vector
const __m256i perm = _mm256_setr_epi32( 0, 1, 2, 4, 5, 6, 7, 7 );
return _mm256_permutevar8x32_epi32( vals, perm );
}
评论
_mm256_shuffle_epi8
仅在每个 128 位通道内随机播放。您可以将它与或实现您想要的结合使用。根据上下文,可能会有更优雅的解决方案(例如,您从哪里获取数据,以及之后如何处理它)。_mm256_permute4x64_epi64
_mm256_permutevar8x32_epi32
vpshufb
vpermb