にパックされたバイトが与えられた場合xmm0
、各バイトの符号 (つまり最上位) ビットを に抽出する効率的な方法は何xmm1
ですか? AND
つまり、パックされたバイトごとに 0x80 で論理を計算したいと考えています。
例えば:
xmm0: 0xff 0xef 0x80 0x7f 0x01 ...
xmm1: 0x80 0x80 0x80 0x00 0x00 ...
バイト要素のシフト (psrlb
または何でも) がないため、右シフトと左シフトで不要なビットをノックオフすることはできません。これを一度だけ行う必要がある場合でも、マスクを使用するのが最善の場合があります.
mask を格納するのに必要な命令バイトよりも少ない命令バイト数でオンザフライでマスクを生成でき、キャッシュ ミスの可能性はありません。
pcmpeqw xmm1,xmm1 ; -1
pabsb xmm1,xmm1 ; 1
psllw xmm1, 7 ; set1_epi8(0x80)
pand xmm1, xmm0
符号ビットを整数 reg にまとめたい場合
PMOVMSKB reg, xmm0
ただし、それをベクトルにアンパックすると、signbit-mask を生成するよりも遅くなります ( AVX512 まで)。
これを 1 回だけ行う場合は、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
いいえ、短くはありませんでした。必要なものによっては、このアイデアの一部が役立つ場合があります。