如何在 AVX256 中对齐/旋转 2 位矢量?

How to align/rotate a 256 bit vector in AVX2?

提问人:cyborgdennett 提问时间:10/18/2023 最后编辑:cyborgdennett 更新时间:10/20/2023 访问量:149

问:

我正在使用 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]

Rust SIMD 内部函数 AVX AVX2

评论

1赞 chtz 10/18/2023
对于 32 位条目,您可以通过_mm256_permutevar8x32_epi32
0赞 cyborgdennett 10/18/2023
@chtz谢谢你,这有用。对于想知道的人:将向左移动您的矢量。从右边的 6 开始。_mm256_permutevar8x32_epi32(vec1, _mm256_set_epi32(0,7,6,5,4,3,2,1))
1赞 harold 10/18/2023
“在我看来,它正在做 128 位版本的低部分和高部分”——是的,一般来说,SSE2+ 操作以“两个并排”的形式升级到 AVX2。
0赞 chtz 10/19/2023
_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]
1赞 Peter Cordes 10/19/2023
_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))pshufdpalignrvpalignr

答:

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 的负载很可能不值得。