SSE2 直接测试 xmm 位掩码而不使用 'pmovmskb'
SSE2 test xmm bitmask directly without using 'pmovmskb'
考虑一下我们有这个:
....
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
使用ptest
:
ptest xmm0, xmm0
jz .zero
ptest a, b
如果 a
∧ b
为零,则设置 ZF,如果 a
∧ ¬ b
为零,则设置 CF。
但请注意,ptest
需要 SSE 4.1。
否则,我想你的做法是as good as it gets。
通常不值得在 pcmpeqb
结果上使用 SSE4.1 ptest xmm0,xmm0
,尤其是在分支时。
pmovmskb
是 1 uop,并且 cmp
或 test
可以与 jnz
宏融合到 Intel 和 AMD CPU 上的另一个单 uop。 使用 pmovmsk + test/jcc
在 pcmpeqb 结果上分支的总计 2 微指令
但是 ptest
是 2 微指令,它的第二微指令 不能 宏与后续分支融合。 使用 ptest
+ jcc.
在向量上分支的总计 3 微指令
当您可以直接使用 ptest
而无需 pcmp
时,这就是收支平衡,例如测试整个向量中的任何/所有位(或使用掩码,一些位)。如果您将它用于 cmov 或 setcc 而不是分支,则实际上是一场胜利。这也是代码大小的胜利,即使相同数量的 uops。
您可以分摊对多个向量的检查。 例如por
将一些向量放在一起,然后检查所有字节是否为零。或者 pminub
一些向量在一起,然后检查 any 零。 (像 strlen 和 strchr 这样的 glibc 字符串函数使用这个技巧来并行检查整个缓存行的向量,然后在离开循环后找出它来自哪里。)
您可以合并 pcmpeq 结果而不是原始输入,例如对于 memchr。在这种情况下,您可以使用 pand
而不是 pminub
在 any 输入具有零的元素中获得零。一些 CPU 运行 pand
在比 pminub
更多的端口上,因此向量 ALU 的竞争较少。
另请注意,pmovmskb 零扩展到 EAX;您可以 test eax,eax
而不是浪费前缀字节来仅测试 AX。
考虑一下我们有这个:
....
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
使用ptest
:
ptest xmm0, xmm0
jz .zero
ptest a, b
如果 a
∧ b
为零,则设置 ZF,如果 a
∧ ¬ b
为零,则设置 CF。
但请注意,ptest
需要 SSE 4.1。
否则,我想你的做法是as good as it gets。
通常不值得在 pcmpeqb
结果上使用 SSE4.1 ptest xmm0,xmm0
,尤其是在分支时。
pmovmskb
是 1 uop,并且 cmp
或 test
可以与 jnz
宏融合到 Intel 和 AMD CPU 上的另一个单 uop。 使用 pmovmsk + test/jcc
但是 ptest
是 2 微指令,它的第二微指令 不能 宏与后续分支融合。 使用 ptest
+ jcc.
当您可以直接使用 ptest
而无需 pcmp
时,这就是收支平衡,例如测试整个向量中的任何/所有位(或使用掩码,一些位)。如果您将它用于 cmov 或 setcc 而不是分支,则实际上是一场胜利。这也是代码大小的胜利,即使相同数量的 uops。
您可以分摊对多个向量的检查。 例如por
将一些向量放在一起,然后检查所有字节是否为零。或者 pminub
一些向量在一起,然后检查 any 零。 (像 strlen 和 strchr 这样的 glibc 字符串函数使用这个技巧来并行检查整个缓存行的向量,然后在离开循环后找出它来自哪里。)
您可以合并 pcmpeq 结果而不是原始输入,例如对于 memchr。在这种情况下,您可以使用 pand
而不是 pminub
在 any 输入具有零的元素中获得零。一些 CPU 运行 pand
在比 pminub
更多的端口上,因此向量 ALU 的竞争较少。
另请注意,pmovmskb 零扩展到 EAX;您可以 test eax,eax
而不是浪费前缀字节来仅测试 AX。