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を使用しています。
私は通常 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;
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時間を使用することに注意してください。
私が完全に同意する次のテキストは、 C++でソフトウェアを最適化する (C++プログラマーにとって良い読み物)から引用されています-
時間間隔が短い場合、時間測定には非常に高い分解能が必要になる場合があります。 Windowsでは、
GetTickCount
またはQueryPerformanceCounter
関数を使用してミリ秒の解像度を得ることができます。 CPUのタイムスタンプカウンターを使用すると、CPUクロック周波数でカウントすることで、はるかに高い解像度を得ることができます。
「クロック周波数が動的に変化する可能性があり、割り込みやタスクの切り替えにより測定が不安定になる」という問題があります。
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);