2016-04-12 9 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 

あなたは符号ビットをしたい場合は、整数REG

PMOVMSKB reg, xmm0 

に一緒に詰めしかし、ベクトルにその背を開梱してsignbitマスク(until AVX512)を生成するよりも遅くなります。あなたは一度だけこれをやっている場合は


、あなたは ESP、4するinsnより短い何かを思い付くことができるかもしれません。 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 

いいえ、これ以上短くはありませんでした。必要なものによっては、このアイデアの一部が役立つかもしれません。

関連する問題