Windows API提供の高分解能パフォーマンス計測QueryPerformanceCounter
関数についてメモ。
簡易的に書いておきますと
- WinXPではQueryPerformance系はCPUクロックを返すので上記の現象が起こる
- WinVista以上でHPETが有効の時はQueryPerformance系はHPETより時間を取得するようになっているのでほとんど問題はない
- ほぼすべてのPCにはHPETで参照されるクロックが実装されている
となっています。WinVista以前を無視するのであればそこまで「使えない」と言うことはないと思われますが、注意は必要です。
http://d.hatena.ne.jp/shiku_otomiya/20100218/p1
MSDNにさらっと酷い記述が… この記事でもスレッドAffinityは固定せよとある。
- 2015-01-30追記:
QueryPerformanceCounter
ドキュメントの Remarks は整理され、Acquiring high-resolution time stamps に情報集約された模様。
Remarks
On a multiprocessor computer, it should not matter which processor is called. However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL). To specify processor affinity for a thread, use the SetThreadAffinityMask function.
メモ:
- 動作クロックが動的変化するプロセッサでは不正確と言われていたが、Windows Vista以降なら大丈夫な可能性が高い。とはいえ、結局は動作環境依存。
- 短期間タイマとしてのみ利用すること。(経験則だが)マルチメディア処理等の長期間タイマとしては、ドリフト誤差が乗るため使い物にならない。素直にマルチメディアタイマ timeGetTime 関数を使うこと。
- 計測精度 10〜15 msecで十分なら GetTickCount 関数が最も手軽。Vista以降なら GetTickCount64 関数も提供される。*1
- クロック単位のマイクロベンチマークなら rdtsc 命令@x86系など。
関連URL
*1:前者は 49.7 日で 32bit カウンタ値がラップアラウンドするが、後者は 64bit カウンタ値のため 5.8 億年は大丈夫!