【发布时间】:2017-03-14 23:41:13
【问题描述】:
我有这段代码:
#include <iostream>
#include <thread>
long int global_variable;
struct process{
long int loop_times_ = 0;
bool op_;
process(long int loop_times, bool op): loop_times_(loop_times), op_(op){}
void run(){
for(long int i=0; i<loop_times_; i++)
if (op_) global_variable+=1;
else global_variable-=1;
}
};
int main(){
struct process p1(10000000, true);
struct process p2(10000000, false);
std::thread t1(&process::run, p1);
std::thread t2(&process::run, p2);
t1.join();
t2.join();
std::cout <<global_variable<< std::endl;
return 0;
}
Main 函数启动两个线程来增加和减少一个全局变量。 如果我用这个编译:
g++ -std=c++11 -o main main.cpp -lpthread
我在每次执行中得到不同的输出。 但是如果我添加 -O3 并用这个编译:
g++ -O3 -std=c++11 -o main main.cpp -lpthread
每次输出为零
这里发生了什么样的优化来消除我的关键部分,我怎样才能欺骗编译器不优化它?
编辑:操作系统:Ubuntu 16.04.4,g++:5.4.0
【问题讨论】:
-
你当前代码的结果可以在编译时计算出来。您是否尝试将迭代次数作为 2 个不同的参数传递给程序并像这样运行它? ./a.out 10000000 10000000
-
我希望通过更快的优化,第一个线程甚至可能在另一个线程开始之前完成...... in 运行速度非常快吗?增加数字直到需要更长的时间,然后查看行为是否恢复。
-
要查看进行了哪些优化,请查看生成的机器代码。检查优化和未优化版本之间的差异。
-
那么代码实际上并没有循环——它以某种聪明的方式计算结果。我怀疑他的第一个线程正在立即完成,将全局增加 N,然后第二个线程也在做同样的事情并减少它。
-
您使用的是什么编译器版本?什么操作系统?由于这是未定义的行为,因此这些事情很重要。如您所见,here 您的示例在不同的机器上给出了不同的结果。
标签: c++ compiler-optimization critical-section