提问人:cyborgdennett 提问时间:10/18/2023 最后编辑:cyborgdennett 更新时间:10/20/2023 访问量:149
如何在 AVX256 中对齐/旋转 2 位矢量?
How to align/rotate a 256 bit vector in AVX2?
问:
我正在使用 AVX2 内部函数,并希望获得以下内容:
输入:[1,2,3,4,5,6,7,8]
输出:[8,1,2,3,4,5,6,7]
以下内容适用于 128 位向量:
let vec1 = _mm_set_epi32(1,2,3,4);
let vec2 = _mm_alignr_epi8(vec1, 4); // shift values one position, catch at bottom
vec1 将给出 vec2 将给出 .
这是预期的。[1,2,3,4]
[4,1,2,3]
使用 256 位向量
let vec256_1 = _mm256_set_epi32(1,2,3,4,5,6,7,8);
let vec256_2 = _mm256_alignr_epi8(vec256_1, 4); // shift values one position
vec256_1会给vec256_2会给[1,2,3,4,5,6,7,8]
[4,1,2,3,8,5,6,7]
所以在我看来,它正在做 128 位版本的低部分和高部分。
我的问题是:我怎样才能做到这一点,以便整个 256 位向左移动一个值?
目的:如何获取以下向量:[8,1,2,3,4,5,6,7]
答:
2赞
Soonts
10/20/2023
#1
如果您负担得起常量向量,请执行以下操作:
__m256i rotate1( __m256i v )
{
const __m256i perm = _mm256_setr_epi32( 7, 0, 1, 2, 3, 4, 5, 6 );
return _mm256_permutevar8x32_epi32( v, perm );
}
如果您宁愿不加载内存,这里有另一个版本,它可以在 2 条指令中完成您想要的操作:
__m256i rotate2( __m256i v )
{
// Make another vector with 16-byte pieces flipped
__m256i flipped = _mm256_permute2x128_si256( v, v, 0x01 );
// With these two vectors, `vpalignr` can rotate the complete input
return _mm256_alignr_epi8( v, flipped, 12 );
}
评论
0赞
Peter Cordes
10/21/2023
2 指令版本也适用于不是 4 字节倍数的旋转,这与第一个版本不同,在 AVX-512 之前没有粒度小于 32 位的通道交叉洗牌。
0赞
cyborgdennett
10/21/2023
我真的很喜欢 rotate2 函数。谢谢!只有 1 个额外的周期,但除非您经常使用 Rotate,否则 Rotate1 的负载很可能不值得。
评论
_mm256_permutevar8x32_epi32
_mm256_permutevar8x32_epi32(vec1, _mm256_set_epi32(0,7,6,5,4,3,2,1))
_mm256_set_epi32(8,7,6,5,4,3,2,1)
或者也应该作为随机向量,即,如果你有一个,你可以从每个条目中添加或减去一个偏移量,以相应地旋转。_mm256_set_epi32(6,5,4,3,2,1,0,-1)
[7,6,..,0]
_mm_alignr_epi8
接受 2 个向量输入。要旋转 1 个向量,您必须使用 .或者,在没有 AVX 的情况下,哪个可以更有效(是复制和随机播放,但会修改其目标。相关新闻: AVX2 中的 _mm_alignr_epi8 (PALIGNR) 等效物 / 如何使用 AVX2 有效地连接两个向量的半相关一般情况?(VPALIGNR的车道交叉版本)_mm_alignr_epi8(vec1, vec1, 4)
_mm_shuffle_epi32(vec1, _MM_SHUFFLE(2,1,0,3))
pshufd
palignr
vpalignr