抛砖:VS的编译器到底做了什么?

        最近在学习并发程序设计,其中有个很重要的概念叫原子操作。网上有很多文章论述原子操作的,其中大部分文章不约而同的都使用到了这个例子——“++”操作,来例证很多高级语言中的一条语句并非是不可拆分的原子操作。出于好奇,本人对“++”操作的原子性在VS2012下写了一个小程序以测试之,于是乎发现了下面的问题。

//测试代码
TEST(ConcurrenceTest, Atomic)
{    
    std::vector<std::thread> threads;
    threads.push_back(std::thread(std::ref(thread)));
    threads.push_back(std::thread(std::ref(thread)));
    for(auto &t : threads)
    {
        t.join(); 
    }
    std::cout<<"total值:"<<total<<std::endl;
}
//线程
void thread()
{
    for(int i = 0; i < 50000; i++)
    {
        total++;
    }
}

        以上代码在release下结果都是100000,但在debug下会小于100000。

        了解原子操作的朋友应该知道,debug下小于100000的结果应该属正常现象,因为“++”操作并不具有原子性,所有在并发的过程中会出现数据竞跑的现象。但是在release下所得到的结果却总是正确的(为了避免偶然性,本人用更多的线程,更大的数据类型同样做过测试,结果依然正确),这不得不怀疑编译器在release下对代码是否做过一定的优化? 那么这种优化对于程序员来说是一件好事么? 他会不会给一些对此了解不深的程序员造成一种正确的假象?本人是个初学者,写这些的目的只是抛个砖,以上的观点也仅是本人的一些小想法,希望有兴趣的朋友能来一起讨论。

posted on 2013-01-09 22:03  MoZhao  阅读(467)  评论(1编辑  收藏  举报

导航