2016-10-02 60 views
0

我試圖通過使用std :: chrono來計算for循環的持續時間,但它給出了0納秒,即使我通過增加循環需要更長的時間綁定的值,這是代碼:std :: chrono的計數持續時間給出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 

但是當我increament綁定循環的計數器,以非常非常巨大的價值突然需要永遠! ,如果我把c < 100000000它需要0 nanosec,但如果我加一個'0'在右邊,它需要永遠!

答案: 爲WhiZTiM說,編譯器去除循環,因爲它沒有任何用處(感謝GCC < 3),但我們真的不希望,當我們正在測試,以算法來看看發生在不同的編譯器(而不是這個特定的編譯器)中速度更快,爲此,我們可以在循環中插入一條asm行。 asm(""),一個空的asm,循環中的任何地方。這將告訴編譯器有一些他不能優化的低級操作! ,或者我們可以對循環中使用的任何變量使用volitile關鍵字,以防止編譯器進行與該變量相關的任何優化。感謝大家我希望這有助於

+0

x,y和z是未初始化的。未定義的行爲。 –

+0

我稍後添加了它們,現在它們已初始化,但問題仍然存在! –

回答

0

首先,利用初始化變量是a sin.

優化器肯定想出循環是無用的(真的,應該是什麼的x值,yz在環) ;並且沒有使用循環的結果(沒有副作用),所以它刪除了生成的代碼中的循環。

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;; 
} 

查看它Live On Coliru

+0

是的,我也這麼認爲:),令人驚歎的海灣合作委員會是awsome XD,我後來添加了x,y,z變量,他們不是原因,現在他們被初始化,但沒有改變任何東西,所以你可以給一個不可忽視的循環示例? –

+0

@DhiaHassen,是的,請看我最新的答案。 – WhiZTiM

+0

謝謝,我們也可以使用'volatile int c;'作爲循環計數器,它可以防止編譯器做任何相關的優化 –