2017-09-20 3 views
2

avx2レジスタ内の32ビットint値のビット反転を実行する方法はありますか? など。avx2レジスタのビット反転

_mm256_set1_epi32(2732370386); 
<do something here> 
//binary: 10100010110111001010100111010010 => 1001011100101010011101101000101 
//register contains 1268071237 which is decimal representation of 1001011100101010011101101000101 
+0

AVX2整数レジスタ内の1つのint32のビットを反転するか、8個の整数の各ビットを反転したいとしますか? –

+1

@JohnZwinck、それは本当に問題ではありません。いったんそれを行う方法がわかったら、好きな方法でレジスタ内の32ビット値をシャッフルできます。 –

+0

古い方法(逆バイト、 'pshufb'の4つの逆グループ、ORの結果)はAVX2に一般化されますが、私はすぐに二倍体を見つけることはできません。 – harold

答えて

5

適切なデュプリが見つからないため、投稿するだけです。

ここでの主なアイデアは、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は、最初のシャッフルを複製しています。

+1

AVX2 [here](https://stackoverflow.com/a/24058332/995714) –

+0

@LưuVĩnhPhúcはいいいえ、私はSSEタグだけを検索していました。 – harold

+0

@LưuVĩnhPhúcあなたのリンクのソリューションは、32の代わりにバイトを反転します-bit ints。 – wim