Mona で microsecond 精度で時刻を知りたい

OSDev.org View topic - RTC and microseconds での回答が良くまとまっているので自分用に日本語でまとめておく。

RTC

RTC の読み出しは秒フィールドまでしかない。

IRQ を使う方法

RTC を periodic interrupt 設定にする事で 2Hz - 8192Hz で割り込みを起こす事が出来る。ただし全てのチップセットで動く事を保証したいなら 1024 Hz が限界。その場合およそ 1 msec 間隔となる。 また割り込み毎に遅い port へのアクセスがあるのでおすすめできない。

また PIT、local APIC, HPET を利用すれば求める精度での割り込みを発生させる事が可能だが、割り込み処理のコストの方が大きくなってしまうので意味がない。
つまり IRQ を使う方法はうまくいかない。

タイマーを読み出す方法

割り込みとタイマーの remaining count を利用する方法。

  1. PIT を 1 秒間に 1000 回割り込みが来るように設定する。
  2. 割り込みハンドラでシステム起動からの msec を更新する。
  3. 精度の高い時刻が必要になったら time = ms_since_boot + (max_PIT_count - current_PIT_count) で 1 microsecond 精度が得られる。


PIT を使用した、この方法の問題は gettimeofday 相当の呼び出し時に毎回 count 読み取りが発生しこれが遅いことである。
同様に local APIC であれば 1 nanosecond の精度が得られる。

HPET

HPET のレジスタを読み出して current_time = HPET_count * K + time_at_boot とする。

RDTSC

高精度でオーバーヘッドが小さいが CPU の sleep status や power management の影響を受け正しい値をとるのが難しい。また別のプロセッサとの sync も問題。
以前 id:kosaki さんにいただいたアドバイス

HPET, local APIC

全ての chipset で使えるわけではない事に注意。

結論

PIT かな。