2016-04-12 11 views
2

Даны упакованные байты в xmm0, что является эффективным способом извлечения знака (то есть наивысшего порядка) бит каждого байта в xmm1? Другими словами, я хочу, чтобы вычислил логический AND с 0x80 для каждого упакованного байта.SSE: Как извлечь бит знака для каждого упакованного байта в упакованный регистр?

Например:

xmm0: 0xff 0xef 0x80 0x7f 0x01 ... 
xmm1: 0x80 0x80 0x80 0x00 0x00 ... 
+0

Вы пробовали '_mm_and_si128()'? – Mysticial

+0

Я могу представить, используя '_mm_and_si128' (т. Е.' Pand'), но для этого требуется сначала загрузить соответствующую маску. (Какой самый эффективный способ сделать это?) Мне интересно, есть ли что-то специализированное, которое может сделать лучше. – jacobsa

ответ

3

Там нет байт-элемент сдвига (psrlb или любой другой), так что вы не можете просто сбить биты вы не хотите с правой и затем сдвиг влево. Даже если вам нужно сделать это только один раз, лучше всего использовать маску.

Вы можете generate the mask on the fly in fewer instruction bytes than it takes to store the mask, не имея возможности пропустить кеш.

pcmpeqw xmm1,xmm1  ; -1 
pabsb xmm1,xmm1  ; 1 
psllw xmm1, 7  ; set1_epi8(0x80) 
pand xmm1, xmm0 

Если вы хотите знаковые биты упакованы вместе в целочисленном обл

PMOVMSKB reg, xmm0 

Но распаковка, что обратно в вектор медленнее, чем генерации signbit-маски (until AVX512).


Если вы только делаете это один раз, вы могли быть в состоянии придумать что-то короче, чем 4 insns, особ. если вы можете использовать неразрушающие операции AVX. Вот идея, которая не была короче:

vpcmpeqw xmm1, xmm1,xmm1 
vpsignb  xmm2, xmm1, xmm0  ; xmm2 = -1 or +1 (or 0) depending on xmm0 
vpsubb  xmm3, xmm2, xmm1  ; xmm3 = 0 or +2 (or +1) depending on xmm0. (subtract -1 => add 1) 
vpsllw  xmm4, xmm3, 6  ; xmm4 = 0 or 0x80 (or 0x40) depending on xmm0 

Нет, не был короче. В зависимости от того, что вам нужно, часть этой идеи может помочь.

 Смежные вопросы

  • Нет связанных вопросов^_^