適切なデュプリが見つからないため、投稿するだけです。
ここでの主なアイデアは、pshufb
のデュアル使用で、各ニブルのビットを反転させるためのパラレル16エントリテーブルの参照を使用することです。バイトを反転させることは明らかです。ルックアップテーブルにそれを組み込む(シフトを保存する)か、明示的に下位部分をシフトする(LUTをセーブする)ことで、各バイトで2つのニブルの順序を逆転させることができます。合計で、このような
何かが、テストされない:
__m256i rbit32(__m256i x) {
__m256i shufbytes = _mm256_setr_epi8(3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12);
__m256i luthigh = _mm256_setr_epi8(0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15, 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15);
__m256i lutlow = _mm256_slli_epi16(luthigh, 4);
__m256i lowmask = _mm256_set1_epi8(15);
__m256i rbytes = _mm256_shuffle_epi8(x, shufbytes);
__m256i high = _mm256_shuffle_epi8(lutlow, _mm256_and_si256(rbytes, lowmask));
__m256i low = _mm256_shuffle_epi8(luthigh, _mm256_and_si256(_mm256_srli_epi16(rbytes, 4), lowmask));
return _mm256_or_si256(low, high);
}
をループにおける典型的な文脈では、これらの負荷は、アウト解除されなければなりません。
奇妙なことに、Clang uses 4 shufflesは、最初のシャッフルを複製しています。
AVX2整数レジスタ内の1つのint32のビットを反転するか、8個の整数の各ビットを反転したいとしますか? –
@JohnZwinck、それは本当に問題ではありません。いったんそれを行う方法がわかったら、好きな方法でレジスタ内の32ビット値をシャッフルできます。 –
古い方法(逆バイト、 'pshufb'の4つの逆グループ、ORの結果)はAVX2に一般化されますが、私はすぐに二倍体を見つけることはできません。 – harold