2013-04-02 5 views
3

__m128i 레지스터의 0이 아닌 값을 추출해야합니다. 예를 들어 8 개의 부호없는 short가있는 벡터가 있습니다.SSE로 _m128i 레지스터에서 0이 아닌 값 추출

__m128i vector {40, 0, 22, 0, 0, 0, 0, 8} 

최소한의 SSE 명령으로 40, 22 및 8을 추출하고 싶습니다. 0이 아닌 값은 0이 아닌 값의 배열에 저장됩니다.

{40, 22, 8, more values from different vectors ... } 

임의로 추출 할 수 있습니까? 추출하거나 저장하는 것이 좋은가요?

+0

SSE 4를 가정 할 수 있습니까? –

+0

네,하지만 SSSE3를 선호 할 수 있습니다. –

+0

0이 아닌 값의 순서를 보존해야합니까? –

답변

2

at this paper으로 보이는 경우 _mm_cmpestrm 명령어를 사용하여 기본적으로 원하는대로 수행하는 방법을 설명합니다.

__m128i res_v = _mm_cmpestrm(
    vector, 
    8, 
    mm_setzero_si128(), 
    8, 
    _SIDD_UWORD_OPS|_SIDD_CMP_EQUAL_ANY|_SIDD_BIT_MASK|_SIDD_NEGATIVE_POLARITY); 
int r = _mm_extract_epi32(res_v, 0); 

__m128i p = _mm_shuffle_epi8(vector, sh_mask[r]); 

종이에 설명 된대로 룩업 테이블 sh_mask을 구축 할 경우, 그들의 알고리즘의 핵심은이 (내가 약간 수정했습니다하는 대신에 그들이 원하는 것을, 당신이 원하는 것을 할)입니다 p는 0이 아닌 요소 (순서를 바꾸지 않고)와 0 요소가 있어야합니다. r에 설정된 비트 수는 0이 아닌 요소의 수를 알려줍니다.

_mm_cmpestrm은 SSE4에 있습니다.

+0

와우 나는이 명령을 알지 못했고, sh_mask로 그 트릭을 정말 멋지다. 고마워. –

2
이 anjruu의 대답을 바탕으로, 여기에 어떤 식 으로든에서 테스트되지 않은 SSSE3 버전의

:

; xmm0 = input 
pxor xmm1, xmm1 
pcmpeqb xmm1, xmm0 
pmovmskb eax, xmm1 
shl eax, 4 
pshufb xmm0, [table + eax] 

table이 운동 할 물론 다른,하지만 어려운 일이 아니다, 그냥 마음에 계속 그 인덱스는 "반전"됩니다. 예를 들어, 인덱스 0은 0이없고, 0xFFFF는 모두 0입니다.

관련 문제