Sin*_*pse 6 c++ optimization multithreading gcc
我正在优化一个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;
}
Run Code Online (Sandbox Code Playgroud)
这基本上启动一个线程,在一秒之后将更改hitto 的值true.同时代码进入一个空循环,这个循环将一直持续到hit值为止true.我gcc-5.4使用-g旗帜编译了这一切,一切都很好.代码将输出finished并结束.但后来我用-O2flag 编译它,这次代码无限地卡在循环中.
查看反汇编,编译器生成了以下内容,这是无限循环的根本原因:
jmp 0x6ba6f3!0x00000000006ba6f3
好吧,很明显,编译器已经推断出它hit的值是false并且它不会在循环中改变所以为什么不假设它是一个无限循环而不考虑另一个线程可能改变它的值!并且此优化模式添加在更高级别(-O2)中.由于我不是一个优化标志专家,任何人都可以告诉我其中哪一个对此结果负责,所以我可以将其关闭?关闭它会对其他代码有任何重大的性能成本吗?我的意思是,这种代码模式有多少是罕见的?
此代码具有未定义的行为.您正在hit从一个线程进行修改并从另一个线程读取它,而不进行同步.
优化hit为false未定义行为的有效结果.您可以通过解决这个问题hit一个std::atomic<bool>.如果定义明确,则会阻止优化.