2016-10-02 24 views
0

私はstd :: chronoを使ってforループで取った時間を数えようとしていましたが、ループを長くしても時間が長くても0ナノ秒です私はそれが突然、永遠にかかる非常に非常に大きな値にループのカウンタのバウンドをincreamentときstd :: chronoでカウントする時間が0ナノ秒になる

token time : 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;; 
} 

出力:バインドされた値は、これはコードです、私はCを置く場合< 100000000それは0ナノ秒かかるが、私は1つの '0'を追加する場合は、それは永遠にかかる!

答え: WhiZTiMはそれが(おかげGCC < 3)便利な何もしませんが、我々は本当に私たちが見るためのアルゴリズムをテストしているとき、それが起こるしたくないので、コンパイラはループを削除して、言ったように異なるコンパイラで高速化すると(この特殊なコンパイラではない)、ループにasm行を挿入することができます。 asm("")、空のasm、ループ内の任意の場所。これは、彼が最適化できない低レベルの操作があることをコンパイラに伝えます。ループ内で使用されている変数にvolitileキーワードを使用すると、コンパイラがその変数に関連する最適化を実行できなくなります。おかげでみんな私は、これは初期化された変数を(ループ内xの値がどうあるべきか、本当に、yz)間違いなくループは無用だった考え出しa sin.

ザ・オプティマイザれる使用して、すべての

+0

X、YおよびZは初期化されていない参照。未定義の動作。 –

+0

後で追加しましたが、初期化されましたが問題は解決しません。 –

答えて

0

初の役に立てば幸い;ループの結果は使用されず(副作用なし)、生成されたコードのループが削除されました。

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

ええ、私はあまりにもそう思った:) gccはawsome XDで、x、y、z変数を後で追加したが、これは原因ではなく、今は初期化されているので何も変わらない。ループの例は無視できませんか? –

+0

@DhiaHassen、はい、私の更新された回答をご覧ください。 – WhiZTiM

+0

ありがとう、ループカウンタに 'volatile int c;'を使うことができます。コンパイラがそれに関連する最適化を行えないようにします –

関連する問題