SSE3 では、PALIGNR 命令は次のことを実行します。
PALIGNR は、デスティネーション オペランド (第 1 オペランド) とソース オペランド (第 2 オペランド) を中間コンポジットに連結し、バイト粒度でコンポジットを定数即値分だけ右にシフトし、右揃えの結果をデスティネーションに抽出します。
私は現在、SSE4 コードを移植して AVX2 命令を使用し、128 ビットではなく 256 ビット レジスタに取り組んでいる最中です。単純に、組み込み関数_mm256_alignr_epi8
(VPALIGNR) が 256 ビット レジスタに対してのみ同じ操作を実行すると信じていました_mm_alignr_epi8
。残念ながら、そうではありません。実際、_mm256_alignr_epi8
256 ビット レジスタを 2 つの 128 ビット レジスタとして扱い、隣接する 2 つの 128 ビット レジスタに対して 2 つの「整列」操作を実行します。と同じ操作を効果的に実行します_mm_alignr_epi8
が、一度に 2 つのレジスタに対して実行します。ここに最も明確に示されています: _mm256_alignr_epi8
現在、私の解決策は、次のよう_mm_alignr_epi8
に、ymm (256 ビット) レジスタを 2 つの 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命令はありますか?