SSE2直接测试xmm位掩码,而不使用'pmovmskb'

问题描述 投票:0回答:2

考虑到我们有这个:

....
pxor            xmm1, xmm1
movdqu          xmm0, [reax]
pcmpeqb         xmm0, xmm1
pmovmskb        eax,  xmm0
test            ax , ax
jz              .zero
...

有没有办法不使用'pmovmskb'并直接从xmm0测试位掩码(以检查其是否为零)?此操作有任何SSE指令吗?

实际上,我正在搜索类似'ptest xmm0,xmm0'的动作,但是在SSE2中...而不是SSE4

assembly bitmask sse2
2个回答
0
投票

使用ptest

ptest

[ptest xmm0, xmm0 jz .zero 如果ptest a, b is a为零,则设置ZF;如果b∧¬a为零,则设置CF。

但是请注意,b必须存在SSE 4.1。

否则,我想您的方法是ptest


0
投票

通常不值得在as good as it gets结果上使用SSE4.1 ptest xmm0,xmm0,尤其是在分支的情况下尤其如此。>

pcmpeqb是1个uop,并且pmovmskbcmp可以与test宏融合到Intel和AMD CPU上的另一个单个uop中。在pcmpeqb结果上总共分支了2微码。

但是jnz是2 uops,它的第二个uop cant

带有后面分支的宏保险丝。总共3微码要在一个向量上分支。

当您无需使用ptest即可直接使用ptest时,收支平衡。测试整个向量中的任何/所有位(或使用掩码,一些位)。如果将其用于cmov或setcc而不是分支,则实际上是一个胜利。即使代码数量相同,这也是代码大小的胜利。


您可以分摊对多个向量的检查。

例如pcmp将某些向量组合在一起,然后检查所有字节为零。或将por一些向量放在一起,然后检查any零。 (诸如strlen和strchr之类的glibc字符串函数使用此技巧来并行检查整个向量的高速缓存行,然后在离开循环后找出其来源。)

您可以合并pcmpeq结果而不是原始输入,例如对于memchr。在这种情况下,可以使用pminub代替pandany

输入为零的元素中得到零。一些CPU在pminub上运行的端口要多于pand,因此对向量ALU的竞争较少。
© www.soinside.com 2019 - 2024. All rights reserved.