マスクに基づいて左にパッキングするための効率的な AVX2 実装
SSE とは異なり、AVX にはマスクに基づいて左にパッキングするための専用の命令がありません。ただし、AVX2 命令と BMI2 命令を組み合わせて使用すると、このタスクを効率的に実行できます。
AVX2 と BMI2 の使用
このアプローチでは、vpermps (_mm256_permutevar8x32_ps) 命令を利用します。これは、レーン交差変数シャッフルを実行し、pdep BMI2 からの (_pdep_u64) 命令。ビットごとの抽出を提供します。
アルゴリズム ステップ
実装詳細
以下のコードは、AVX2 BMI2 の実装を提供します。
#include <immintrin.h> __m256 compress256(__m256 src, unsigned int mask) { uint64_t expanded_mask = _pdep_u64(mask, 0x0101010101010101); // unpack each bit to a byte expanded_mask *= 0xFF; // mask |= mask<<1 | mask<<2 | ... | mask<<7; // ABC... -> AAAAAAAABBBBBBBBCCCCCCCC...: replicate each bit to fill its byte const uint64_t identity_indices = 0x0706050403020100; // the identity shuffle for vpermps, packed to one index per byte uint64_t wanted_indices = _pext_u64(identity_indices, expanded_mask); __m128i bytevec = _mm_cvtsi64_si128(wanted_indices); __m256i shufmask = _mm256_cvtepu8_epi32(bytevec); return _mm256_permutevar8x32_ps(src, shufmask); }
パフォーマンス分析
この実装では、16c で 6 の uops が発生します。待ち時間。複数の反復を実行中に維持しながら、4 サイクルごとに 1 反復のスループットを維持できる可能性があります。
代替アプローチ
Zen 3 より前の AMD CPU の場合、pext/pdep非常に遅いため、別のアプローチの方が望ましい場合があります。 16 ビット要素の場合は、128 ビット ベクトルのアプローチを使用できます。 8 ビット要素の場合、複数の重複チャンクを含む別の手法を使用できます。
以上がAVX2 および BMI2 命令は、マスクに基づいてレフト パッキングを効率的に実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。