Share via


高分解能タイマー

Windows 8.1 以降、ドライバーは ExXxxTimer ルーチンを使って高解像度タイマーを管理できます。 高解像度タイマーの精度は、システム クロックでサポートされる最大解像度によってのみ制限されます。 これに対し、既定のシステム クロック解像度に制限されているタイマーの精度は、大幅に低下します。

ただし、高解像度タイマーでは、システム クロックの割り込みが (少なくとも一時的に) 高い割合で発生する必要があるため、消費電力が増加する傾向があります。 したがって、ドライバーは、タイマーの精度が重要な意味を持つ場合のみ高解像度タイマーを使用し、それ以外のすべての場合は既定の解像度のタイマーを使用する必要があります。

高解像度タイマーを作成するため、WDM ドライバーは ExAllocateTimer ルーチンを呼び出し、Attributes パラメーターに EX_TIMER_HIGH_RESOLUTION フラグを設定します。 ドライバーが ExSetTimer ルーチンを呼び出して高解像度タイマーを設定すると、オペレーティング システムは必要に応じてシステム クロックの解像度を上げ、タイマーが期限切れになる時刻が DueTime パラメーターと Period パラメーターで指定された名目の有効期限に、より正確に対応するようにします。

カーネル モード ドライバー フレームワーク (KMDF) ドライバーは、WdfTimerCreate メソッドを呼び出して、高解像度タイマーを作成できます。 この呼び出しでは、WDF_TIMER_CONFIG 構造へのポインターがドライバーからパラメーターとして渡されます。 高解像度タイマーを作成するには、ドライバーは、この構造の UseHighResolutionTimer メンバーを TRUE に設定します。 このメンバーは、Windows 8.1 および KMDF バージョン 1.13 以降の構造の一部です。

タイマー精度の制御

たとえば、x86 プロセッサで実行されている Windows の場合、システム クロック ティック間の既定の間隔は通常約 15 ミリ秒で、システム クロック ティック間の最小間隔は約 1 ミリ秒です。 したがって、既定の解像度タイマー (EX_TIMER_HIGH_RESOLUTION フラグが設定されていない場合に ExAllocateTimer によって作成される) の有効期限は約 15 ミリ秒以内に制御できますが、高解像度タイマーの有効期限は 1 ミリ秒以内に制御できます。

ドライバーが既定の解像度タイマーの相対有効期限を指定した場合、タイマーは、指定された有効期限よりも約 15 ミリ秒前または後に期限切れになる可能性があります。 ドライバーが高解像度タイマーの相対有効期限を指定した場合、タイマーは、指定された有効期限が切れてから約 1 ミリ秒後に期限切れになる可能性がありますが、有効期限より早く期限切れになることはありません。 システム クロックの解像度とタイマーの精度の関係について詳しくは、「タイマーの精度」をご覧ください。

高解像度タイマーが設定されていない場合、オペレーティング システムは通常、システム クロックを既定のレートで実行します。 ただし、1 つ以上の高解像度タイマーが設定されている場合、オペレーティング システムは、これらのタイマーの有効期限が切れる前に、少なくとも一部の時間の最大レートでシステム クロックを実行する必要があります。

不必要な電力消費の増加を回避するため、オペレーティング システムは、高解像度タイマーのタイミング要件を満たすのに必要な場合のみ、システム クロックを最大レートで実行します。 たとえば、高解像度タイマーが定期的であり、その期間が複数の既定のシステム クロック ティックにまたがる場合、オペレーティング システムは、各有効期限の直前のタイマー期間の一部でのみ、システム クロックを最大レートで実行できます。 残りのタイマー期間では、システム クロックは既定のレートで実行されます。

過剰な電力消費を防ぐため、ドライバーは、長時間実行される高解像度タイマーの期間を、システム クロック ティック間の既定の間隔よりも小さい値に設定しないようにする必要があります。 そうしないと、オペレーティング システムはシステム クロックを最大レートで継続的に実行するよう強制されます。

Windows 8 以降、ドライバーは ExQueryTimerResolution ルーチンを呼び出し、システム クロックによってサポートされているタイマー解像度の範囲を取得できます。

ExSetTimerResolution との比較

Windows 2000 以降では、ドライバーは ExSetTimerResolution ルーチンを呼び出して、連続するシステム クロック割り込みの時間間隔を変更することができます。 たとえば、ドライバーは、このルーチンを呼び出して、システム クロックを既定のレートから最大レートに変更し、タイマーの精度を向上させることができます。 ただし、ExSetTimerResolution の使用には、ExAllocateTimer によって作成された高解像度タイマーの使用に比べて、いくつかの欠点があります。

まず、ExSetTimerResolution を呼び出してシステム クロック レートを一時的に上げた後、ドライバーは ExSetTimerResolution を 2 回目に呼び出してシステム クロックを既定のレートに復元する必要があります。 それ以外の場合、システム クロック タイマーは最大レートで割り込みを継続的に生成するため、過剰な電力消費が発生する可能性があります。

2 つ目に、ExSetTimerResolution ルーチンを使用するドライバーは、オペレーティング システムが高解像度タイマーに対して行うほどには、より高いシステム クロック レートの一時的な使用を効率的に最適化できません。 したがって、システム クロックは、厳密に必要な時間よりも最大レートで実行される時間が長くなります。

3 つ目は、複数のドライバーが同時に ExSetTimerResolution を使用してタイマーの精度を向上させる場合、システム クロックが長時間最大レートで実行される可能性があります。 これに対し、オペレーティング システムは、複数の高解像度タイマーの動作をグローバルに調整し、これらのタイマーのタイミング要件を満たすために必要な場合のみシステム クロックが最大レートで実行されるようにします。

最後の点として、ExSetTimerResolution の使用は、本質的に高解像度タイマーを使用するよりも正確ではありません。 ドライバーが ExSetTimerResolution を呼び出してシステム クロックを最大レート (通常はミリ秒あたりのティック数) まで大きくした後、ドライバーは KeSetTimerEx などのルーチンを呼び出してタイマーを設定する可能性があります。 この呼び出しで、ドライバーが相対有効期限を指定する場合、タイマーは、指定された有効期限よりも約 1 ミリ秒前または後に期限切れになる可能性があります。 ただし、高解像度タイマーに対して相対有効期限が指定されている場合、タイマーは、指定された有効期限より約 1 ミリ秒後に期限切れになる可能性がありますが、有効期限より早く期限切れになることはありません。