2024/06/03 電子書籍「電子書籍出版・技術文書作成を劇的に加速!秀丸エディタ + Markdown + Pandocの驚異」を出版

タイマーの精度の向上

C++Builder

Windowsで、タイマーの精度を向上させる方法について説明します。

MS-DOSのタイマーの精度

先ず、MS-DOSのTickタイマーの精度を確認しましょう。

以下、Chat-GPTの回答です。約55msですね。

MS-DOSのタイマーの精度は約55ミリ秒です。これは、MS-DOSのタイマーが一般的に18.2ヘルツ(Hz)で動作するためです。1秒間に18.2回の割合でタイマー割り込みが発生し、したがって、タイムスライスが約55ミリ秒となります。この精度はMS-DOSの古いバージョンで一般的であり、より新しいオペレーティングシステムでは高い精度のタイマーが提供されます。

Chat-GPTの回答

Windowsのタイマーの精度

次に、Windowsのタイマーの精度を確認しましょう。

こちらも、Chat-GPTに聞いてみましょう。通常、約15.6msですね。

Windows 7およびそれ以前のバージョンでは、通常のタイマー精度は約15.6ミリ秒(ミリ秒)です。これは、1秒間に64回のタイマー割り込み(約1000ミリ秒/64 ≈ 15.6ミリ秒)が発生することを意味します。

Chat-GPTの回答

timeBeginPeriod 関数を使用したタイマーの精度向上

timeBeginPeriod関数を使用して、タイマーの精度を向上させる事が出来ます。通常、1msまで精度を向上させることができます。

以下、参考コードです。以下のSetMSTimer()関数を、コンストラクタ等から呼び出すことで、タイマーの精度を、1msに変更する事ができます。Sleep等の精度が、1msの精度となります。

// タイマーの高精度化   #include <mmsystem.h>   // timeGetTime
UINT SetMSTimer(void)
{
    DWORD msec = (DWORD)timeGetTime();
    UINT i = 1;
    while ( i <= 1000 )
    {
        if ( timeBeginPeriod( i ) == TIMERR_NOERROR )   // if ( timeBeginPeriod( i ) != TIMERR_NOCANDO )
        {
            break;
        }
        i++;
    }
    return i; // timeEndPeriod 
}

コンストラクタで、セット。

timePeriod = SetMSTimer();

FormCloseで、timeEndPeriod関数を実行。

timeEndPeriod(timePeriod);

timeBeginPeriod 関数使用時の注意点

timeBeginPeriod関数を使用して、タイマーの精度を向上させた場合の注意点として、その変更がWindows全体に及ぶことです。Windows 10バージョン 2004 より前のバージョンでは、timeBeginPeriod関数を実行したアプリケーションだけではなく、全てのアプリケーションのタイマーの精度が変更されます。Windows 10バージョン 2004 以降は、実行したアプリケーションのタイマー精度のみが変更されるようです。

以下、timeBeginPeriod 関数のヘルプより、

Windows 10バージョン 2004 より前のバージョンでは、この関数はグローバル Windows 設定に影響します。
すべてのプロセスについて、Windows では、任意のプロセスによって要求された最小値 (つまり、最高の解像度) が使用されます。
バージョン 2004 Windows 10以降、この関数はグローバル タイマー解決に影響しなくなりました。

imeBeginPeriod 関数のヘルプより
timeBeginPeriod 関数 (timeapi.h) - Win32 apps
timeBeginPeriod 関数は、定期的なタイマーの最小解像度を要求します。

参考URL

以下のURLも参照ください。

タイトルとURLをコピーしました