linuxで時刻を取得する方法について調査した.(2006/7/17更新)
時刻を取得する方法としては
- システムコールを呼び出し,時刻を管理しているデバイス(RTCとかカーネル内部のオブジェクト)を読む方法
- userlandから直接CPUが持っているクロックのレジスタを読む方法(x86だとRDTSC命令)
がある.両者は
- 移植性が高い.オーバヘッドが大きい
- 移植性が低い.オーバヘッドが小さい.
という関係にある.また後者の方法を取る場合は,CPUが複数あるSMP環境では,CPUが持っているクロックのレジスタが同期していないことも考慮しなければならない.
glibcが提供するAPIと,その内部の動作をまとめてみる.
- time_t time(time_t *tloc);
- 精度が悪いので調査は省略
- int ftime(struct timeb *tp);
- 精度が悪いので調査は省略
- int gettimeofday(struct timeval *tv, struct timezone *tz);
- 内部ではシステムコール sys_gettimeofday を利用
- clock_gettime(CLOCK_MONOTONIC)
- clock_gettime(CLOCK_REALTIME)
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID)
- clock_gettime(CLOCK_THREAD_CPUTIME_ID)
このように glibc の実装では,glibcとkernelの組み合わせで挙動が変わる.そこで実際の動作を strace を使って調査した
API | linux-2.4.33 libc-2.3.2 Xeon smp | linux-2.6.17 libc-2.3.6 Xeon smp | linux-2.6.17 libc-2.4 Pen4 HT | |
---|---|---|---|---|
gettimeofday | sys_gettimeofday | sys_gettimeofday | sys_gettimeofday | |
CLOCK_MONOTONIC | sys_gettimeofday | sys_clock_getime | sys_clock_getime | |
CLOCK_REALTIME | 利用不可 | sys_clock_getime | sys_clock_getime | |
CLOCK_PROCESS_CPUTIME_ID | 利用不可 | RDTCS | sys_clock_getime | |
CLOCK_THREAD_CPUTIME_ID | 利用不可 | RDTCS | sys_clock_getime |