给定 中的压缩字节xmm0
,将每个字节的符号(即最高阶)位提取到 中的有效方法是什么xmm1
?换句话说,我想AND
为每个打包字节计算 0x80 的逻辑。
例如:
xmm0: 0xff 0xef 0x80 0x7f 0x01 ...
xmm1: 0x80 0x80 0x80 0x00 0x00 ...
没有字节元素移位(psrlb
或其他),所以你不能用右移然后左移来敲掉你不想要的位。即使您只需要这样做一次,最好还是戴上口罩。
您可以使用比存储掩码所需的指令字节更少的指令字节动态生成掩码,而不会出现缓存未命中的情况。
pcmpeqw xmm1,xmm1 ; -1
pabsb xmm1,xmm1 ; 1
psllw xmm1, 7 ; set1_epi8(0x80)
pand xmm1, xmm0
如果您希望将符号位打包在一个整数 reg 中
PMOVMSKB reg, xmm0
但是将其解压缩回向量比生成符号位掩码要慢(直到 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
不,没有更短。根据您的需要,这个想法的一部分可能会有所帮助。