web-dev-qa-db-ja.com

正確な時間測定

C++でtime.hを使用して、関数のタイミングを測定しています。

clock_t t = clock();
someFunction();
printf("\nTime taken: %.4fs\n", (float)(clock() - t)/CLOCKS_PER_SEC);

ただし、時間は常に0.0000になっています。 clock()とtを別々に印刷すると、同じ値になります。 C++で正確に時間を測定する方法があるかどうか(ナノ秒程度)を知りたいと思います。 VS2010を使用しています。

44
Abhishek Thakur

私は通常 QueryPerformanceCounter 関数を使用します。

例:

LARGE_INTEGER frequency;        // ticks per second
LARGE_INTEGER t1, t2;           // ticks
double elapsedTime;

// get ticks per second
QueryPerformanceFrequency(&frequency);

// start timer
QueryPerformanceCounter(&t1);

// do something
...

// stop timer
QueryPerformanceCounter(&t2);

// compute and print the elapsed time in millisec
elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
56
Constantinius

C++ 11は chrono API を導入しました。これを使用してナノ秒を取得できます。

auto begin = std::chrono::high_resolution_clock::now();

// code to benchmark

auto end = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(end-begin).count() << "ns" << std::endl;

より適切な値を得るには、関数を数回実行して平均を計算するのが良いでしょう:

auto begin = std::chrono::high_resolution_clock::now();
uint32_t iterations = 10000;
for(uint32_t i = 0; i < iterations; ++i)
{
    // code to benchmark
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end-begin).count();
std::cout << duration << "ns total, average : " << duration / iterations << "ns." << std::endl;

ただし、forループとbeginおよびend varの割り当てにもCPU時間を使用することに注意してください。

91
Axel Guilmin

私が完全に同意する次のテキストは、 C++でソフトウェアを最適化する (C++プログラマーにとって良い読み物)から引用されています-

時間間隔が短い場合、時間測定には非常に高い分解能が必要になる場合があります。 Windowsでは、GetTickCountまたはQueryPerformanceCounter関数を使用してミリ秒の解像度を得ることができます。 CPUのタイムスタンプカウンターを使用すると、CPUクロック周波数でカウントすることで、はるかに高い解像度を得ることができます。

「クロック周波数が動的に変化する可能性があり、割り込みやタスクの切り替えにより測定が不安定になる」という問題があります。

6
SChepurin

CまたはC++では、通常以下のようにします。それでも失敗する場合は、rtdsc関数の使用を検討してください。

      struct timeval time;
      gettimeofday(&time, NULL); // Start Time

      long totalTime = (time.tv_sec * 1000) + (time.tv_usec / 1000);

          //........ call your functions here

        gettimeofday(&time, NULL);  //END-TIME

        totalTime = (((time.tv_sec * 1000) + (time.tv_usec / 1000)) - totalTime);
2
hmatar