簡體   English   中英

使用std :: chrono計數持續時間會花費0納秒

[英]counting duration with std::chrono gives 0 nanosecond when it should take long

我試圖使用std :: chrono計算for循環所花費的持續時間,但是即使我通過取消綁定值使循環花費更長的時間,它也給出了0納秒,這是代碼:

#pragma pack(1) // dont align let's let it take longer
struct Foo{
    int x;
    char c;
    int z;
} ;
void take_time()
{
    Foo f;
    auto t1 = std::chrono::system_clock::now();
    register int c = 0;
    int x=0,y=0,z=1;
    for (c=0;c<10000;c++){ // even if i put  1000000000 it will take 0 nanosec !!!!!
        f.z = x+y;
        f.z += z-x+y;
    }
   std::cout<<"\ntoken time : "<< std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()-t1).count()<<std::endl;;
}

輸出:

token time : 0

但是,當我使循環計數器的邊界值達到非常非常大的值時,它突然變得永遠永久! ,如果我把c <100000000花費了0納秒,但是如果我在右邊加上一個“ 0”,那將永遠花費!

答案 :正如WhiZTiM所說,編譯器正在刪除循環,因為它沒有任何用處(感謝gcc <3),但是我們真的不希望在測試算法時發現這種情況發生,因為在不同的編譯器上速度更快(不是這個特別的),為此,我們可以在循環中插入一個asm行。 asm("") ,一個空的asm,在循環中的任何位置。 這將告訴編譯器有些無法優化的底層操作! ,或者我們可以將volitile關鍵字用於循環中使用的任何變量,以防止編譯器進行與該變量相關的任何優化。 謝謝大家,我希望這會有所幫助

首先,使用初始化變量是一種罪過。

優化器肯定認為循環是無用的(實際上,循環中xyz的值應該是什么); 並且沒有使用循環的結果(沒有副作用),因此它在生成的代碼中刪除了循環。

void take_time()
{
    Foo f;
    auto t1 = std::chrono::system_clock::now();
    register int c = 0;
    int x,y,z;

    ///// Result not used
    for (c=0;c<10000;c++){ // even if i put  1000000000 it will take 0 nanosec !!!!!
        f.z = x+y;
        f.z += z-x+y;
    }
    /// We can discard the above

   std::cout<<"\ntoken time : "<< std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()-t1).count()<<std::endl;;
}

順便說一句,不推薦使用那里的register關鍵字。


對於GCC和clang,有一種方法可以“嚇跑”優化器,以免優化某些變量的使用。 我使用此功能:

template<typename T>
void scareTheOptimizer(T& x){
    asm volatile("" :: "p"((volatile void*)&x) : "memory");
}

因此,當您在循環中調用它時,現在應該看到一些時間。

void take_time()
{
    Foo f;
    auto t1 = std::chrono::system_clock::now();
    int c = 0;
    int x=0,y=0,z=1;
    for (c=0;c<10000;c++){
        f.z = x+y;
        scareTheOptimizer(f.z);             /// <---- Added Here
        f.z += z-x+y;
    }
   std::cout<<"\ntoken time : "<< std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now()-t1).count()<<std::endl;;
}

在Coliru上實時觀看

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM