web-dev-qa-db-ja.com

Cでの時間の測定

C(行列乗算)でいくつかのアクティビティを測定しようとしていますが、次のようなことを行う必要があることに気付きました。

clock_t start = clock();
sleep(3);
clock_t end = clock();
double elapsed_time = (end - start)/(double)CLOCKS_PER_SEC;
printf("Elapsed time: %.2f.\n", elapsed_time);

出力は次のとおりです。

Elapsed time: 0.00.

なんでこんなことが起こっているの?

18
aalf1987

clockは、プログラムが使用するCPU時間を推定します。これは、CPUがプログラムに属する命令の実行でビジー状態であった時間です。 sleepは何の処理も実行しないため、(壁時計の時間がかかっていても)顕著なCPU時間はかかりません。

ウォールクロック時間を測定する場合は、timeを使用します。

time_t start = time(NULL);
sleep(3);
printf("%.2f\n", (double)(time(NULL) - start));

3に近い数を印刷します。

29
Fred Foo

補足として、実行時間をより正確な方法(ミリ秒)で測定したい場合、 time は十分に正確ではありません。代わりに gettimeofday を使用できます:

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>

int main() {
    long start, end;
    struct timeval timecheck;

    gettimeofday(&timecheck, NULL);
    start = (long)timecheck.tv_sec * 1000 + (long)timecheck.tv_usec / 1000;

    usleep(200000);  // 200ms

    gettimeofday(&timecheck, NULL);
    end = (long)timecheck.tv_sec * 1000 + (long)timecheck.tv_usec / 1000;

    printf("%ld milliseconds elapsed\n", (end - start));

    return 0;
}
6
Romuald Brunet

正しい値を取得するには、time_t start = time(NULL);およびtime_t end = time(NULL);を使用する必要があります。

1
Aniket Inge

オーウェルズの回答で説明されているように QueryPerformanceFrequency() を使用するか、または GetSystemTimeAsFileTime() 関数を使用します。後者の粒度は100 nsですが、その速度では増加しません。その増分は、基盤となるハードウェアと マルチメディアタイマー解像度 の設定に依存します。 QueryPerformanceFrequency()によって返される頻度は定数として扱われることに注意してください。ただし、ハードウェアによって生成されるため、オフセットや時間のずれもあります。 QueryPerformanceCounter()を使用して時間を測定すると、通常、1秒あたり数マイクロ秒のエラーが発生します。同様の問題について thisthis で回答しました。

0
Arno

Windowsに縛られることを気にしない場合は、高解像度タイマーを試すことができます。これはUNIX形式を使用しているため、time()よりもはるかに正確であり、1秒の精度しかありません。

#include <iostream>
#include <windows.h>

__int64 countspersec = 0;
double secpercount = 0.0;
__int64 starttime = 0;
__int64 curtime = 0;

int main() {

    // Get current time, and determine how fast the clock ticks
    QueryPerformanceCounter((LARGE_INTEGER*)&starttime);
    QueryPerformanceFrequency((LARGE_INTEGER*)&countspersec);
    secpercount = 1.0/(double)countspersec;

    /* calculate something */

    // Standard end-start stuff, account for clock speed
    QueryPerformanceCounter((LARGE_INTEGER*)&curtime);
    std::cout << "Time needed: " << (curtime-starttime)*secpercount << " sec\n";
    return 0;
}
0
Orwell