问题描述
基本上,我正在尝试了解以下位置的代码:https://gcc.godbolt.org/z/7xxb3G
{3}
编译为:
void __attribute__((noinline))
cond_unset_bit(uint64_t * v,uint32_t b) {
if(__builtin_expect(!!(*v & ((1UL) << b)),1)) {
*v ^= ((1UL) << b);
}
}
基于Agner Fog's Instruction Table(skylake是第238页),cond_unset_bit(unsigned long*,unsigned int):
movq (%rdi),%rax
btq %rsi,%rax
jnc .L6
btcq %rsi,%rax
movq %rax,(%rdi)
.L6:
ret
和btq
在寄存器上进行操作的成本完全相同。 btcq
也会set the carry flag to the previous bit,因此似乎不需要使用btcq
指令即可实现完全相同的逻辑(具有更好的性能),即:
btq
包括cond_unset_bit(unsigned long*,%rax
btcq %rsi,%rax
jnc .L6
movq %rax,(%rdi)
.L6:
ret
的原因是什么?
我正在调整x86_64 / Intel Skylake芯片
编辑: 感谢@Peter Cordes(以及我其他所有帖子的帮助:)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)