2012-03-15 62 views
6

虽然与VS11测试版打我注意到一个很奇怪: 这个代码COUTS编译器可以通过对std :: chrono :: system_clock :: now()的调用重新排序代码吗?

˚F了0毫秒

int main() 
{ 
    std::vector<int> v; 
    size_t length =64*1024*1024; 
    for (int i = 0; i < length; i++) 
    { 
     v.push_back(rand()); 
    } 

    uint64_t sum=0; 
    auto t1 = std::chrono::system_clock::now(); 
    for (size_t i=0;i<v.size();++i) 
     sum+=v[i]; 
    //std::cout << sum << std::endl; 
    auto t2 = std::chrono::system_clock::now(); 
    std::cout << "f() took " 
     << std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count() 
       << " milliseconds\n"; 


} 

但是,当我决定以取消与总和couting的线路则打印出合理的数字。

这是我与优化得到的行为启用,禁用它们,我得到“正常”的cout

F()花了471毫秒

因此,这是符合标准的行为? 重要提示:并不是死代码被优化,我可以看到从控制台运行时的滞后,我可以看到任务管理器中的CPU峰值。

回答

9

我的猜测是,这是代码优化 - 和您的负载峰值是由于工作初始化被优化掉的载体,但您未使用sum变量的计算是

但是,当我决定取消注释该线的总和,然后它打印出一个合理的数字。

这与我的理论一致,是的 - 当你被迫使用计算结果时,计算本身不能被优化。

如果您想进一步确认,请在您的程序准备好并暂停时按下回车键 - 这将允许您在按回车键之前等待任何CPU峰值明显“消失”,这将会让你对导致它的更多信心。

+0

检查,你是对的,但现在我感到困惑,如果明智地找出这个总和没有使用为什么它在做初始化?我猜这不能证明rand()没有副作用... – NoSenseEtAl 2012-03-15 00:30:42

+0

ouch ... ofc它不能证明rand没有副作用 - rand不是一个纯函数...它有状态。 :)但即使替换rand()与我仍然不能防止初始化... – NoSenseEtAl 2012-03-15 00:32:14

+0

@NoSenseEtAl:那么初始化工作使用'push_back' ...所以我的猜测是,即使编译器可能能够告诉'v '只能在后面以丢弃的方式使用,假设'push_back()'不会有其他副作用。但我不想肯定地说。 – 2012-03-15 06:18:27

相关问题