gpt4 book ai didi

c++ - gcc优化对具有明显常量变量的循环的影响

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:20:43 25 4
gpt4 key购买 nike

我在优化一段c++代码时,遇到了一种情况,可以简化如下。

考虑这段代码:

#include <iostream>
#include <thread>

using namespace std;

bool hit = false;

void F()
{
this_thread::sleep_for(chrono::seconds(1));
hit = true;
}

int main()
{
thread t(F);

while (!hit)
;

cout << "finished" << endl;
t.join();
return 0;
}

这基本上启动了一个线程,该线程将在一秒钟后将 hit 的值更改为 true。同时,代码进入一个空循环,该循环将一直持续到 hit 的值变为 true。我使用 -g 标志用 gcc-5.4 编译了它,一切都很好。代码将输出 finished 并结束。但是后来我用 -O2 标志编译了它,这次代码无限地卡在了循环中。

查看反汇编,编译器生成了以下内容,这是无限循环的根本原因:

jmp 0x6ba6f3 ! 0x00000000006ba6f3

OK,很明显,编译器已经推断出hit的值为false,并且在循环中不会改变,所以为什么不假设它是一个无限的循环而不考虑另一个线程可能会改变它的值!而这种优化模式是在更高层级(-O2)加入的。由于我不完全是优化标志专家,谁能告诉我他们中的哪一个对这个结果负责,所以我可以将其关闭?关闭它会对其他代码段产生任何重大性能成本吗?我的意思是,这种代码模式有多罕见?

最佳答案

这段代码有未定义的行为。您正在修改 hit来自一个线程并从另一个线程读取它,没有同步。

优化 hitfalse是未定义行为的有效结果。你可以通过制作 hit 来解决这个问题一个std::atomic<bool> .这使得 if 定义明确,并阻止了优化。

关于c++ - gcc优化对具有明显常量变量的循环的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46980917/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com