実行時間を調べる処理 (1) 方法を見てみるの記事ではほとんどWindowsのタイマしか説明が無く、
Linux版のタイマについて説明がほとんど無かったので気が向いたので記事に出来る分だけ調べてみました。
Linuxで使える高解像度タイマはclock_gettime関数
POSIXのバージョンにもよりますが、Linuxでは、時間取得にはclock_getres関数、clock_gettime関数、clock_settime関数を使うことで詳細な時間を取得できます。
clock_getres関数は対象のタイマの分解能を取得するため、clock_settimeは基準状態の強制設定で使用しますが、設定できないタイマもあるためあまり使いません。
使うのはclock_gettime関数です。
#define ONESECONNANOSEC 1000000000ll unsigned long long timespecto64bitval(struct timespec *tp) { if(tp == NULL) return 0; return (unsigned long long)((long long)(tp->tv_sec) * ONESECONNANOSEC + (long long)(tp->tv_nsec)); } unsigned long long getdifftimespec(struct timespec *tpd,struct timespec *tpb) { time_t tds; long tdn; if(tpd == NULL || tpb == NULL) return 0; tds = tpd->tv_sec - tpb->tv_sec; tdn = tpd->tv_nsec - tpb->tv_nsec; return (unsigned long long)((long long)tds * ONESECONNANOSEC + (long long)tdn); } int main(void) { struct timespec t1,t2; unsigned long long tb,td; td = ONESECONNANOSEC; clock_gettime(CLOCK_REALTIME,&t1); f(); clock_gettime(CLOCK_REALTIME,&t2); td = getdifftimespec(&t2,&t1); printf("f() took %d count [%4.2f sec].\n",td,(double)td / (double)tb); getchar(); return 0; }
利点
- 取得時にタイマを指定することが出来る(例ではLinuxが参照しているリアルタイムタイマだが、CPUクロックも参照できる)
- 最小単位はnsなのでタイマの分解能さえ高ければWindowsを上回る解像度を得ることも出来る
- timespec構造体上での時間であればまずラウンドすることはない
欠点
- 整数値で取得したい場合、タイマ値を整数値単体に変換するためのヘルパが必要
- 分解能がタイマによって違うため分解能が気になる場合はclock_getres関数により取得して考える必要があり
- 対象のタイマが実装されていないことがあるのでそれはちゃんと調べてから使う必要があり
時間を管理しているtimespec構造体を見る限り、おそらくWebで使用しているサーバーサイドのスクリプト言語もこれを使って時間取得を行っていると思われます。
ソースコードを見れば一発ですが、見る気にはなれないのであくまで想定と言うことで。
Linux上で時間解像度が必要な場合はこれを使うといいでしょう。