***本記事にはプロモーションが含まれています。***
自分のシステムでは、QueryPerformanceFrequency = 3579545 になる。
QEMUの算出するticks_per_secは、1428395429ぐらいになって、400倍くらい違った。
どうしてか調べてみたら、自分のシステムではQueryPerformanceCounterは、ACPIのPM Timer(Power Management Timer)を使っているみたいです。PMタイマーを使っていると、3579545になるんだそうです。ただ、システムによって異なり、たとえば、Win2kだとTSCの値をそのまま返すシステムもあるそうです。
QEMUは、RDTSCというアセンブラ命令で得られるTSC(Time Stamp Counter)を使っていました。TSCとPMタイマーが400倍くらい違うということらしい。
RDTSCを使うのは、いろいろ問題があるみたいで、Microsoftはゲームの時間測定ではQueryPerformanceCounter/QueryPerformanceFrequencyを使うことを推奨しています。
BIOSやマザーボードのバグで、マルチコアなどのシステムではQueryPerformanceCounterがスレッドで違った値を返すことがあるそうなので、SetThreadAffinityMaskでCPUを指定しなさいとのこと。
AMDのシステムで、32-bit WinXP SP2, 64-bit WinXP, Win2003 SP1のとき、boot.iniに/usepmtimerというオプションをつけることで、マルチコアのTSC(Time Stamp Counter)に依存しないようになるそうです。AMDの人が言っている。
Linuxのブートオプションでは、clock=pit, pmtmr, cyclone, hpet, tscといろいろ時間の測定を変更するオプションがあるんですね。pmtmrというのが、ACPI PM Timerを使うということらしい。
つっこむといろいろ出てきて、時間に関する問題は奥が深いなと思った。