抛砖: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下对代码是否做过一定的优化? 那么这种优化对于程序员来说是一件好事么? 他会不会给一些对此了解不深的程序员造成一种正确的假象?本人是个初学者,写这些的目的只是抛个砖,以上的观点也仅是本人的一些小想法,希望有兴趣的朋友能来一起讨论。