2012-05-12 7 views
3

2つの整数レジスタのペアワイズ比較とSSE命令を使用した等しい要素の抽出の最適な方法は何ですか?たとえば、a = [6 4 7 2]b = [2 4 9 2](各レジスタに4つの32ビット整数が含まれている)の場合、結果は[4 2 x x]になります。この疑問の代替形式は、シャッフルに使用できる等しい要素(..0101b)のバイナリマスクを取得する方法、または事前計算テーブルのシャッフル命令のパラメータを参照するためのインデックスとして使用する方法です。SSEを使用した比較と抽出

+0

減算は等しい数字の組を0に変換します。 –

答えて

2

私はおそらくdrhirschが提案しているもののバリアントを使用します。

int index = _mm_movemask_ps((__m128)_mm_cmp_epi32(a, b)); 

これはあなただけ2つの操作を使用してシャッフルマスクを検索する際に使用する同じインデックスを提供します。

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のコストになります。

+0

実際には、命令をシャッフルする際に直接使用するビットマスク、または事前計算テーブルのマスクを検索するための小さなインデックス、つまりこの例では 'mask = .0101b = 5d。 – user1128016

+0

@ user1128016更新 – hirschhornsalz

関連する問題