c - 当有条件地在 uint64_t * 内存区域中设置一个位时,为什么 gcc 将 btq 与 btcq 结合使用
问题描述
基本上我试图理解代码:https ://gcc.godbolt.org/z/7xxb3G
void __attribute__((noinline))
cond_unset_bit(uint64_t * v, uint32_t b) {
if(__builtin_expect(!!(*v & ((1UL) << b)), 1)) {
*v ^= ((1UL) << b);
}
}
编译为:
cond_unset_bit(unsigned long*, unsigned int):
movq (%rdi), %rax
btq %rsi, %rax
jnc .L6
btcq %rsi, %rax
movq %rax, (%rdi)
.L6:
ret
基于Agner Fog 的指令表(skylake 是第 238 页)btq
,并且btcq
在对寄存器进行操作时具有完全相同的成本。btcq
还将进位标志设置为前一位,因此看起来完全相同的逻辑(具有更好的性能)可以在没有btq
指令的情况下完成,即:
cond_unset_bit(unsigned long*, unsigned int):
movq (%rdi), %rax
btcq %rsi, %rax
jnc .L6
movq %rax, (%rdi)
.L6:
ret
包含的原因是btq
什么?
我正在调整 x86_64 / intel skylake 芯片
编辑:感谢@Peter Cordes(以及对我所有其他帖子的帮助:)
解决方案
推荐阅读
- ios - iOS 如何同步 Main.storyboard 字符串和 Localizable.strings
- windows - Windows 任务计划程序 - 不间断运行任务
- javascript - hide or remove a specific arc in canvas html5
- php - 如何在单击按钮时删除自定义元框?
- python - 将计数器对象的元素相乘
- ruby-on-rails - 使用 Elm 和 Rails 成功运行项目的最小 CircleCI 2 config.yml
- android - 如果 RecyclerView 在 NestedScrollView 内,findLastVisibleItemPosition 返回错误值
- r - 根据第二个数据框的日期范围计算平均浓度
- python - Python - 手动包装一个方法(具体来说,我问的是 robert kern 的 line-profiler )
- c# - 低负载下与数据库的连接问题(dotnet core)