x86 - _mm_alignr_epi8 (PALIGNR) 在 AVX2 中等效

标签 x86 simd intrinsics avx avx2

在 SSE3 中,PALIGNR 指令执行以下操作:

PALIGNR concatenates the destination operand (the first operand) and the source operand (the second operand) into an intermediate composite, shifts the composite at byte granularity to the right by a constant immediate, and extracts the right-aligned result into the destination.



我目前正在移植我的 SSE4 代码以使用 AVX2 指令并处理 256 位寄存器而不是 128 位。
天真地,我相信内在函数 _mm256_alignr_epi8 (VPALIGNR) 执行与 _mm_alignr_epi8 相同的操作仅在 256 位寄存器上。然而,可悲的是,情况并非完全如此。事实上,_mm256_alignr_epi8将 256bit 寄存器视为 2 个 128bit 寄存器,并对两个相邻的 128bit 寄存器执行 2 次“对齐”操作。有效地执行与 _mm_alignr_epi8 相同的操作但同时在 2 个寄存器上。在这里最清楚地说明:_mm256_alignr_epi8

目前我的解决方案是继续使用 _mm_alignr_epi8通过将 ymm(256 位)寄存器拆分为两个 xmm(128 位)寄存器(高和低),如下所示:
__m128i xmm_ymm1_hi = _mm256_extractf128_si256(ymm1, 0);
__m128i xmm_ymm1_lo = _mm256_extractf128_si256(ymm1, 1);
__m128i xmm_ymm2_hi = _mm256_extractf128_si256(ymm2, 0);
__m128i xmm_ymm_aligned_lo = _mm_alignr_epi8(xmm_ymm1_lo, xmm_ymm1_hi, 1);
__m128i xmm_ymm_aligned_hi = _mm_alignr_epi8(xmm_ymm2_hi, xmm_ymm1_lo, 1);
__m256i xmm_ymm_aligned = _mm256_set_m128i(xmm_ymm_aligned_lo, xmm_ymm_aligned_hi);

这有效,但必须有更好的方法,对吗?
是否应该使用更“通用”的 AVX2 指令来获得相同的结果?

最佳答案

你在用什么palignr为了?如果只是为了处理数据错位,只需使用错位加载;它们在现代英特尔 µ 架构上通常“足够快”(并且会为您节省大量代码大小)。

如果您需要 palignr - 出于其他原因的类似行为,您可以简单地利用未对齐的负载支持以无分支的方式执行此操作。除非您完全受加载存储限制,否则这可能是首选的习惯用法。

static inline __m256i _mm256_alignr_epi8(const __m256i v0, const __m256i v1, const int n)
{
    // Do whatever your compiler needs to make this buffer 64-byte aligned.
    // You want to avoid the possibility of a page-boundary crossing load.
    char buffer[64];

    // Two aligned stores to fill the buffer.
    _mm256_store_si256((__m256i *)&buffer[0], v0);
    _mm256_store_si256((__m256i *)&buffer[32], v1);

    // Misaligned load to get the data we want.
    return _mm256_loadu_si256((__m256i *)&buffer[n]);
}

如果您能提供更多关于您如何使用的信息 palignr ,我可能会更有帮助。

关于x86 - _mm_alignr_epi8 (PALIGNR) 在 AVX2 中等效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8517970/

相关文章:

x86 - IA-32中的基本数据类型是什么?

assembly - MS-DOS - 是否可以对 24 位图形进行编程?

debugging - 谁能清楚地解释一下这个拆解吗?

c++ - 优化的 SIMD vector 库是否由等效的标量运算执行?

audio - 跨平台SIMD库是否具有与Accelerate Framework类似的API?

sse - SSE-不存在的hardsub固有的吗?

simd - AVX512中有没有像_mm512_sign_epi16 (__m512i a, __m512i b)这样的函数

assembly - x86 代表前缀,计数为零 : what happens?

c++ - 什么是 _mm_prefetch() 位置提示?

c - 从两个 128 位 block 中收集四个 32 位字