在 SSE3 中,PAligNR 指令执行以下操作:
PARIGNR 将目标操作数(第一个操作数)和源操作数(第二个操作数)连接成一个中间组合,将组合以字节粒度向右移动一个常量立即数,并将右对齐的结果提取到目标中。
我目前正在移植我的 SSE4 代码以使用 AVX2 指令并使用 256 位寄存器而不是 128 位。天真地,我相信内在函数(VALIGNR)执行与仅在 256 位寄存器上_mm256_alignr_epi8
相同的操作。_mm_alignr_epi8
然而可悲的是,情况并非如此。实际上,_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 指令来获得相同的结果?