c++ - 为什么 C++ 编译器不将此条件 bool 赋值优化为无条件赋值?

标签 c++ optimization

考虑以下函数:

void func(bool& flag)
{
    if(!flag) flag=true;
}

在我看来,如果 flag 具有有效的 bool 值,这相当于无条件将其设置为 true,如下所示:

void func(bool& flag)
{
    flag=true;
}

然而 gcc 和 clang 都没有以这种方式对其进行优化——两者都在 -O3 优化级别生成以下内容:

_Z4funcRb:
.LFB0:
    .cfi_startproc
    cmp BYTE PTR [rdi], 0
    jne .L1
    mov BYTE PTR [rdi], 1
.L1:
    rep ret

我的问题是:是否只是代码太特殊而无法优化,或者考虑到 flag 不是引用,是否有充分的理由不希望进行这种优化 volatile ?似乎唯一的原因可能是 flag 可能以某种方式具有非 true-or-false 值而此时没有未定义的行为阅读它,但我不确定这是否可能。

最佳答案

这可能会对程序的性能产生负面影响,因为 cache coherence考虑因素。每次调用 func() 时写入 flag 会弄脏包含缓存行。无论写入的值是否与写入前在目标地址找到的位完全匹配,都会发生这种情况。


编辑

hvd提供了另一个good reason这阻止了这种优化。这是一个反对建议优化的更有说服力的论据,因为它可能导致未定义的行为,而我的(原始)答案仅涉及性能方面。

经过更多思考,我可以再举一个例子,为什么编译器应该被强烈禁止——除非他们可以证明转换对于特定上下文是安全的——从引入无条件写入。考虑这段代码:

const bool foo = true;

int main()
{
    func(const_cast<bool&>(foo));
}

func() 中进行无条件写入,这肯定会触发未定义的行为(写入只读内存将终止程序,即使写入的效果是无操作) .

关于c++ - 为什么 C++ 编译器不将此条件 bool 赋值优化为无条件赋值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40303182/

相关文章:

c++ - 诠释 [0];这个语句有什么用?它在哪里有意义?

php - 优化 mysql 数据库 - 任务列表耗尽了我的服务器

c - 如何在不指定 -O1 的情况下获得 gcc -O1 优化

c++ - 程序在调试器中运行时触发断点,但如果在没有调试器的情况下运行则可以正常工作

optimization - 有效使用英特尔编译器 SVML `__m128 _mm_sincos_ps ()`

c - C程序的可变运行时间

c++ - 访问一个 vector ,它是映射中的一个值,以与另一个 vector 在其上运行相等运算符

c++ - 为什么 std::allocator::deallocate 需要大小?

c++ - 循环提升仍然是 C 代码的有效手动优化吗?