2012-05-12 2 views
3

두 개의 정수 레지스터를 쌍으로 비교하고 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

하나의 명령으로 동등한 요소를 추출하고 이동할 수 없습니다. 그러나 동일한 요소의 마스크는 쉽게 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 

처럼 아마도 직접 드 브루 인의 mulitiplication를 사용하여 셔플을 계산, 셔플을 계산하는 조회 테이블을 사용하는 것보다 더 나은 알고리즘을있을 수 있습니다. OTOH 비교할 int가 4 개 이상인 경우 추가 4 int는 하나만phaddd의 비용으로 올 것입니다.

+0

저는 실제로 명령을 셔플 링하거나 직접 계산 된 테이블에서 마스크를 검색하기위한 작은 인덱스 (예 :이 예제에서는'mask =)로 사용할 수있는 비트 마스크를 의미합니다. .0101b = 5d'. – user1128016

+0

@ user1128016 업데이트 됨 – hirschhornsalz

관련 문제