処理負荷計測について
仕事が忙しいと言い訳しているうちに気付けば10月になってしまいました。。。
本当はもっと頑張るつもりなんです。本当は。。。
ただ何をするにも時間がなければ何も出来ません。
そしてそれはプログラムも一緒です!
たとえどんなにすごいプログラムでも重ければ使い物になりません!
ゲームでは1フレームに使える時間が
60FPSの場合は約16.6ms
30FPSの場合は約33.3ms
たったこれだけしか使えません。
重い場合には複数フレームに渡って処理する方法や並列処理での対処も考えられますが、それでも限界があります。
それに重い処理がどこなのかが分からなければどうしようもありません。
そんな時に必要になってくるのが誰もが知ってるストップウォッチです!
ただストップウォッチといっても今回のような場合はプログラム上にストップウォッチを用意する必要があります。
今回はWindows環境でのその方法を簡単に書いていきます。
それでは早速ストップウォッチのプログラムから行ってみましょう!
class StopWatch { public: StopWatch(void) { // 高分解能の周波数を取得 QueryPerformanceFrequency(&m_Freq); } void Reset(void) { // 開始時間の取得 QueryPerformanceCounter(&m_Start); } double Sec(void) const { // 開始時間の取得 LARGE_INTEGER End; QueryPerformanceCounter(&End); const LONGLONG TICK_DELTA = 1000000000; const double INV_TICK_DELTA = 1.0 / (double)TICK_DELTA; return (double)(((End.QuadPart - m_Start.QuadPart) * TICK_DELTA) / m_Freq.QuadPart) * INV_TICK_DELTA; } double MilliSec(void) const { return Sec() * 1000.0; } double MicroSec(void) const { return Sec() * 1000000.0; } private: LARGE_INTEGER m_Freq; // 周波数 LARGE_INTEGER m_Start; // 開始時間 };
はい、たったこれだけです!
これさえあればどんな処理も時間を図り放題!
プログラムを始めたばかりの人はよくTimeGetTimeを使ったりしますが、
これだと戻り値がDWORDになっていますので2の32乗の精度までしかとることができません。
又、最小単位がミリ秒なのでマイクロ単位の値もとることができません。
1フレームが十数ミリ秒しかないようなゲームではこの精度は致命的と言えます。
なので今回使用しているのは高分解能のパフォーマンスカウンタを使用しています。
これはハードウェアの周波数に応じて計測の制度が変わるものになるんですが、
最近の数GHzあるCPUの性能であれば大体マイクロ秒単位までは十分な精度で取得が可能です。
※自分の環境であれば約300ns単位での取得が可能でした。
このように処理負荷を計測する処理があるだけでどうすれば時間を作れるかを調べることができます!
実際には一つ一つ負荷を図って調べていく必要が出てくるので、負荷の大きそうな場所に仕込んで計測をしていくことになります。
ただ処理を仕込むにもこれだけでは計測をするのが難しいと思いますので、
別の機会に処理負荷をもう少し便利に計測するプロファイラについての説明をしたいと思います。
という訳で今回はこの辺で!
皆さん、夜更かしはほどほどに~。