技術解説 |
パフォーマンスカウンタ |
最終更新日:2007/04/26
全面改訂 |
●概要
ペンティアム以降のCPUでは、内部にハードウェアカウンタを持っている。このカウンタはCPUに供給されるCPUクロックを元にハードウェアでカウントしている。
●原理
ハードウェアカウンタを読み取り、完全自立的に動作しているので正確無比である。電源が投入されてからカウントし始める。但し、折り返しは筆者には不明、多分OSによる。
●アクセス方法
.NET の関数にはなく、Win32 API を利用する。
○宣言
Declare Function QueryPerformanceCounter
Lib "Kernel32" (ByRef X As Long) As Short
Declare Function QueryPerformanceFrequency
Lib "Kernel32" (ByRef X As Long) As Short
○プログラミング
Dim X As Long
・QueryPerformanceCounter(X)
X に、その時のカウンタ値が返る。0 の場合は、Performance
Counter が存在しない。
・QueryPerformanceFrequency(X)
Xに、カウンタに入力されているクロック周波数(単位はHz)が返される。0
の場合は、Performance Counter が存在しない。例えば、3.1GHz
であれば、
X = 3,100,000,000
となる。この逆数がそのシステムにおける理論最小計測時間(秒)となる。
○API使用例
Dim Frq,T1, T2 As Long
QueryPerformanceFrequency(Frq) 'システムのクロック周波数を獲得
If Frq = 0 Then 'エラー
QueryPerformanceCounter(T1) '開始カウント
(被計測ルーティン)
QueryPerformanceCounter(T2) '終了カウント
Dim TT As Double = (T2 - T1)/Frq
'計測された時間(秒)
にて、秒数が得られる。
●時間計測の注意点
- リリースコードであることは言うまでもない。
- .NET VB(C#も同じ)
では、最初、中間コードがロードされ、それが動く。そのとき、ネイティブコードに自動変換され、次回からは(同じインスタンスであれば)ネイティブコードで動く。従って、初めの一回は、インタプリタの実行時間となり遅くなるので捨てる必要がある。
●分解能を知る
計算上の分解能は、1 / QueryPerformanceFrequency
であるが、実際には前後にAPIコールがあり、このオーバーヘッドを考慮する必要がある(下図)。
実測した結果が下表となる。10回の計測と平均値。
マシン P4 3.2GHz Win XP で測定
-
Frq は、3,215,520,000 Hz (約3.2GHz)で、このシステムではCPUクロックがそのまま使用されて
おり、理論分解能は、0.311nS
となる。
-
計測関数のオーバーヘッドは、平均2800カウントで、時間としては平均870nS となる。従って、このシステムでは、誤差10% で10μS
前後の事象までは計測できることになる。
-
一回きりで、このオーバーヘッド時間を差し引くことは容易に考えつくが、変動誤差があり、計算値が負になってしまうこともあるので、その方法は採用できない。なお、時間にはシステムのオーバヘッド時間も含まれている。
|