当在uint64_t *内存区域中有条件地设置位时,为什么gcc与btcq一起使用btq

问题描述

基本上,我正在尝试了解以下位置的代码: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 (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...