c++ - 使用 AVX 模拟 32 字节的移位

标签 c++ simd intrinsics sse2 avx2

我正在将使用 SSE2 内在函数编写的矢量化代码迁移到 AVX2 内在函数。

令我非常失望的是,我发现移位指令 _mm256_slli_si256_mm256_srli_si256 仅分别对 AVX 寄存器的两半进行操作,并且在其间引入了零。 (这与处理整个 SSE 寄存器的 _mm_slli_si128_mm_srli_si128 形成对比。)

你能给我推荐一个简短的替代品吗?

更新:

_mm256_slli_si256 可以通过

高效实现

_mm256_alignr_epi8(A, _mm256_permute2x128_si256(A, A, _MM_SHUFFLE(0, 0, 3, 0)), N)

_mm256_slli_si256(_mm256_permute2x128_si256(A, A, _MM_SHUFFLE(0, 0, 3, 0)), N)

对于大于 16 字节的移位。

但问题仍然存在于 _mm256_srli_si256

最佳答案

我从不同的输入中收集了这些解决方案。跨越车道间障碍的关键是对齐指令,_mm256_alignr_epi8

_mm256_slli_si256(A, N)

0 < N < 16

_mm256_alignr_epi8(A, _mm256_permute2x128_si256(A, A, _MM_SHUFFLE(0, 0, 2, 0)), 16 - N)

N = 16

_mm256_permute2x128_si256(A, A, _MM_SHUFFLE(0, 0, 2, 0))

16 < 数 < 32

_mm256_slli_si256(_mm256_permute2x128_si256(A, A, _MM_SHUFFLE(0, 0, 2, 0)), N - 16)

_mm256_srli_si256(A, N)

0 < N < 16

_mm256_alignr_epi8(_mm256_permute2x128_si256(A, A, _MM_SHUFFLE(2, 0, 0, 1)), A, N)

N = 16

_mm256_permute2x128_si256(A, A, _MM_SHUFFLE(2, 0, 0, 1))

16 < 数 < 32

_mm256_srli_si256(_mm256_permute2x128_si256(A, A, _MM_SHUFFLE(2, 0, 0, 1)), N - 16)

关于c++ - 使用 AVX 模拟 32 字节的移位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25248766/

相关文章:

C++ 在派生类构造函数之前期望主表达式

c - 英特尔 SSE 内在函数 _mm_load_si128 段错误,

c - 如何在 __m128 变量中包含整个复数?

c++ - 使用 AVX2 指令左移 128 位数

c++ - 如何重载其参数仅因 gcc vector 扩展 vector_size 属性不同而不同的函数?

c - 英特尔 AVX 在 C 中的 _mm256_load_si256 整数运算不一致

c++ - 在 C++ 中使用 if(cin>>) 命令

c++ - 解析字符串并交换子字符串

java - 如何在java中执行 "an exe with return value"?

c - 如何避免if语句?因为编译器无法将其优化为 simd