Windows API(QueryPerformanceCounter と QueryPerformanceFrequency)を利用した処理時間の計測方法

Last updated:

C++ Windows

Windows が提供する QueryPerformanceCounter(QPC) と QueryPerformanceFrequency(QPF)を利用した処理時間の計測方法について紹介します。

(※ これらは Windows 固有の API のため、クロスプラットフォームな対応が必要な場合は、その環境ごとに適した API を利用する必要があります。)

QPC と QPF について

QueryPerformanceCounter (QPC)

  • システムが起動してからの累積カウンタ値(ティック数)を取得する関数
  • 1µs(マイクロ秒)未満の精度

QueryPerformanceFrequency (QPF)

  • 1 秒あたりのティック数を取得する関数

経過時間の算出

ある 2 点の QPC を QPF で割ることで、経過時間(秒)を求めることができます。

$$ \Delta QPC = QPC_{\text{end}} - QPC_{\text{start}} $$

$$ \text{Elapsed Time} = \frac{\Delta QPC}{QPF} $$

例)

QPF が 1000(1 ティック = 0.001 秒)で、QPC の開始時点と終了時点が以下のようになっているとします。

$$ QPC_{\text{start}} = 1000, \quad QPC_{\text{end}} = 1300 $$

このとき、QPC の差分(ΔQPC)は、

$$ \Delta QPC = QPC_{\text{end}} - QPC_{\text{start}} = 1300 - 1000 = 300 $$

経過時間は、QPF を用いて以下のように計算できます。

$$ \text{Elapsed Time} = \frac{\Delta QPC}{QPF} = \frac{300}{1000} = 0.3 \text{ 秒} $$

サンプルコード

#include <windows.h>
#include <stdio.h>
#include <stdint.h>

using i64 = std::int64_t;

int main() 
{
    i64 start = 0, end = 0, frequency = 0;

    QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&frequency));

    QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&start));

    // 計測対象となる処理(ここでは 300ms スリープ)
    Sleep(300);

    QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&end));

    // 経過時間(秒)を算出
    double elapsedSeconds = static_cast<double>(end - start) / frequency;

    printf("Elapsed time: %.3f [ms]\n", elapsedSeconds * 1000.0);

    return 0;
}
Elapsed time: 300.176 [ms]

参考資料