测试 256 位 YMM AVX 寄存器为零的最有效/惯用方法
Posted
技术标签:
【中文标题】测试 256 位 YMM AVX 寄存器为零的最有效/惯用方法【英文标题】:Most efficient/idiomatic way to test a 256-bit YMM AVX register for zero 【发布时间】:2014-05-29 16:35:06 【问题描述】:我有一个 x86_64 例程,如果成功,它最终会在 YMM 寄存器中以零结束,如果 YMM 寄存器我想返回非零值。
我有办法通过清除另一个 YMM 寄存器,针对那个寄存器对我的寄存器进行 VPTEST 测试,然后如果未设置 CF,则有条件地递增返回寄存器(在我的情况下为 RAX):
" xor %%rax, %%rax \n" // clear RAX
" vxorpd %%ymm0, %%ymm0, %%ymm0 \n" // clear YMM0
" vptest %%ymm1, %%ymm0 \n" // compare YMM1 to zero
" jc endcheck \n" // branch over if no residue
" inc %%rax \n" // inc RAX otherwise
"endcheck: \n" // result is now in RAX
这似乎有点不透明。有没有更好的方法,或者更惯用或更易读的方法?
【问题讨论】:
您不需要两个 YMM 寄存器,其中一个已被清除 - 只需vptest %%ymm1, %%ymm1
@PaulR,谢谢,这有帮助。然后我在这种情况下使用jz
来识别零。
另外你应该支持无分支代码,你可以使用SETC
/SETNC
甚至ADC
/SBB
。
这里没有扩展程序集,为什么要把它放在这样的字符串中?
【参考方案1】:
结合上面的cmets,可以分三行组装完成:
"xor %%rax, %%rax \n" // clear RAX
"vptest %%ymm1, %%ymm1 \n" // if YMM1 zero, set ZF
"setnz %%al \n" // set byte in RAX if not zero
这似乎更清晰,更符合我的想法。
【讨论】:
以上是关于测试 256 位 YMM AVX 寄存器为零的最有效/惯用方法的主要内容,如果未能解决你的问题,请参考以下文章
AVX2:AVX 寄存器中 8 位元素的 CountTrailingZeros
ASM x86_64 AVX:xmm 和 ymm 寄存器差异