首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >-O3循环增量优化

-O3循环增量优化
EN

Stack Overflow用户
提问于 2017-03-14 15:02:34
回答 2查看 524关注 0票数 3

我有一段代码:

代码语言:javascript
复制
#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函数触发两个线程,增加和减少一个全局变量。如果我用以下方式编译:

代码语言:javascript
复制
 g++ -std=c++11 -o main main.cpp -lpthread

每次执行都会得到不同的输出。但是,如果我添加-O3并使用以下内容进行编译:

代码语言:javascript
复制
g++ -O3 -std=c++11 -o main main.cpp -lpthread

每次输出都是零。

这里发生了什么样的优化,消除了我的关键部分,我如何才能欺骗编译器而不对其进行优化?

编辑: OS: Ubuntu16.04.4,g++:5.4.0

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-14 15:29:09

很可能您的run方法正在被优化为相当于:

代码语言:javascript
复制
 void run(){
      if (op_) global_variable += loop_times_;
            else global_variable -= loop_times_;

这是编译器可以很容易地用可用的信息做的事情。

要欺骗编译器,您必须确保循环不会在每次迭代中添加或减去1,而不会产生其他副作用。

尝试在循环中添加一个函数调用,这只会在名为totalIterationsDone的对象上增加一个简单的计数器,或者类似的。这可能会迫使编译器实际执行循环。将循环变量作为参数传递也可能迫使它跟踪i的中间值。

代码语言:javascript
复制
struct process{
    long int loop_times_ = 0;
    bool op_;
    long int _iterationsDone = 0;
    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;
            Trick(i);
        }
    }

    void Trick(int i){
       _iterationsDone += 1;
    }    
};
票数 2
EN

Stack Overflow用户

发布于 2017-03-14 15:06:17

您的程序有未定义的行为,以数据竞赛的形式出现。两个线程在没有同步的情况下访问一个变量是一种数据竞争,因此没有定义。

删除数据竞争的最简单方法是使global_variable成为原子化的:

代码语言:javascript
复制
std::atomice<long int> global_variable;

代码的其余部分不需要做进一步的更改。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42789511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档