2012-03-15 26 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

相關問題