2つの整数レジスタのペアワイズ比較とSSE命令を使用した等しい要素の抽出の最適な方法は何ですか?たとえば、a = [6 4 7 2]
とb = [2 4 9 2]
(各レジスタに4つの32ビット整数が含まれている)の場合、結果は[4 2 x x]
になります。この疑問の代替形式は、シャッフルに使用できる等しい要素(..0101b
)のバイナリマスクを取得する方法、または事前計算テーブルのシャッフル命令のパラメータを参照するためのインデックスとして使用する方法です。SSEを使用した比較と抽出
答えて
私はおそらくdrhirsch
が提案しているもののバリアントを使用します。
int index = _mm_movemask_ps((__m128)_mm_cmp_epi32(a, b));
これはあなただけ2つの操作を使用してシャッフルマスクを検索する際に使用する同じインデックスを提供します。
1つの命令で同じ要素を抽出して移動することはできません。しかし、簡単にpcmpeqd
で達成することができる等しい要素のマスク:
__m128i zero = _mm_set1_epi32(0);
__m128i a = _mm_set_epi32(6, 4, 7, 2);
__m128i b = _mm_set_epi32(2, 4, 9, 2);
__m128i mask = _mm_cmp_epi32(a, b); // mask is now 0, -1, 0, -1
mask = _mm_sub_epi32(zero, mask); // mask is now 0, 1, 0, 1
編集:あなたがシャッフル定数のルックアップテーブルのためのいくつかのインデックスをしたい場合は は、追加の操作を必要とします。
static const __m128i zero = _mm_set1_epi32(0);
static const __m128i bits = _mm_set_epi32(1,2,4,8);
__m128i a = _mm_set_epi32(6, 4, 7, 2);
__m128i b = _mm_set_epi32(2, 4, 9, 2);
__m128i bitvector = _mm_and_si128(bits, _mm_cmp_epi32(a, b));
bitvector = _mm_hadd_epi32(bitvector, bitvector);
bitvector = _mm_hadd_epi32(bitvector, bitvector);
// now a index from 0...15 is the the low 32 bit of bitvector
のように、おそらく直接デBruijnグラフのmulitiplicationを使用してシャッフルを計算し、シャッフルを計算するためのルックアップテーブルを使用するよりも優れたアルゴリズムがあるかもしれません。 OTOHあなたが4つ以上のintを比較する場合、追加の4 intの値は、の1つで、の追加のphaddd
のコストになります。
実際には、命令をシャッフルする際に直接使用するビットマスク、または事前計算テーブルのマスクを検索するための小さなインデックス、つまりこの例では 'mask = .0101b = 5d。 – user1128016
@ user1128016更新 – hirschhornsalz
- 1. PHP抽出比較演算子
減算は等しい数字の組を0に変換します。 –