高精度イベントタイマー( HPET ) は、最新のx86 互換パーソナルコンピュータで利用可能なハードウェアタイマーです。x86 アーキテクチャで利用可能な古いタイプのタイマーと比較して、HPET は、マルチメディア再生や OSタスク切り替えなど、タイミングに非常に敏感なアプリケーションのより効率的な処理を可能にします。これはIntelとMicrosoftによって共同開発され、2005 年以降PC チップセットに組み込まれています。以前は Intel によってマルチメディアタイマーと呼ばれていましたが[ 1 ]、 HPET という用語は、 Windows 3.0のマルチメディア拡張機能で導入されたソフトウェアマルチメディアタイマーとの混同を避けるために選択されました。[ 2 ]
ハードウェアHPETデバイスをサポートしていない古いオペレーティングシステムでは、プログラマブルインターバルタイマー(PIT)やリアルタイムクロック(RTC)などの古いタイミング機能しか使用できません。最新のハードウェア抽象化レイヤー(HAL)を搭載したWindows XPでは、プロセッサのタイムスタンプカウンタ(TSC)またはACPI電源管理タイマー(ACPI PMTIMER)をRTCと併用して、後のWindowsバージョンでHPETハードウェアによって提供されるオペレーティングシステム機能を提供することもできます。紛らわしいことに、このようなWindows XPシステムでは、Intel HPETデバイスが使用されていないにもかかわらず、デバイスドライバマネージャに「HPET」接続が表示されます。
HPETチップは、少なくとも10MHzの周波数でカウントする64ビットアップカウンタ (メインカウンタ)と、(少なくとも3個、最大256個の)コンパレータのセットで構成されています。これらのコンパレータは32ビットまたは64ビット幅です。HPETは、ACPI経由で検出可能なメモリマップドI/Oウィンドウを介してプログラムされます。最新のPCでは、HPET回路はサウスブリッジチップに統合されています。[ a ]
各コンパレータには値がプログラムされており、メインカウンタの値がプログラムされた値と一致したとき、または32ビットモードでは、メインカウンタ値の下位32ビットがゼロにラップアラウンドするたびに割り込みを生成できます。コンパレータは、ワンショットモードまたは周期モードに設定でき、少なくとも1つのコンパレータが周期モードをサポートし、すべてのコンパレータがワンショットモードをサポートします。ワンショットモードでは、メインカウンタがコンパレータのレジスタに格納された値に達したときに、コンパレータは一度だけ割り込みを発生させます。一方、周期モードでは、指定された間隔で割り込みが生成されます。
コンパレータは、オペレーティングシステムによって駆動される場合もあれば(例えば、スケジューリングのためにCPUごとに1つのタイマーを提供する場合など)、アプリケーションによって駆動される場合もある。
HPETはRTCよりもはるかに高い解像度で周期的な割り込みを生成でき、マルチメディアストリームの同期によく使用され、スムーズな再生を実現し、x86ベースのCPURDTSC命令などの他のタイムスタンプ計算を使用する必要性を減らします。これにより、CPUがタイマーの低解像度を補うためにサイクルを無駄にする必要がなくなり、効率が向上し、スリープ状態をより積極的に使用できるため、消費電力が削減されます。高精度クロックに対するアプリケーションレベルの要求に加えて、スケジューラやマルチプロセッサシステム向けの安定したクロックベースが利用可能になることで、OSレベルにも利点があります。[ 3 ]
HPETは、 8254プログラマブルインターバルタイマーとRTCの周期割り込み機能を補完および置き換えることを目的としています。これらの古いタイマー回路と比較して、HPETはより高い周波数とより広い64ビットカウンタを備えています(ただし、32ビットモードで駆動することもできます)。[ 1 ]
HPET仕様ではタイマー周波数は定義されておらず、最低10MHzを要求するだけです 。実際の周波数は、周期あたりのフェムト秒数(上限は100 000 000 fs)。一般的な値は 14.3 18 MHz で、標準の 8254 周波数 1.193 18 MHz の 12 倍です。
8254 と RTC はHPET のようなワンショットモードに設定できますが、セットアッププロセスが非常に遅いため、正確なスケジューリングを必要とするタスクでは、実際にはワンショットモードは使用されません。[ 4 ]代わりに、8254 と RTC は通常、非常に短い時間間隔の周期モードで使用されます。たとえば、アプリケーションが短い (おそらく数ミリ秒) 待機を複数回実行する必要がある場合、 8254 または RTC ワンショットタイマーのセットアップコストが高いため、周期 1 ms で常に実行される周期タイマーを使用する方が良いです。これにより、アプリケーションが実際の作業を行う頻度が低くても、毎ミリ秒ごとに割り込みが発生します。HPET を使用すると、HPET ワンショットタイマーのセットアップコストがかなり小さいため、余分な割り込みを回避できます。

HPETが登場する以前に設計されたオペレーティングシステムはHPETを使用できないため、他のタイマー機能を使用します。新しいオペレーティングシステムはどちらも使用できる傾向があります。ハードウェアによっては両方を備えているものもあります。実際、現在のほとんどのサウスブリッジチップには、オペレーティングシステムで使用されるかどうかに関わらず、PIT、PIC、 APIC( Advanced Programmable Interrupt Controller)、RTCといったレガシーデバイスをサポートするインスタンスがシリコンに組み込まれており、最新のPCでも古いオペレーティングシステムを実行できるようになっています。
以下のオペレーティングシステムはHPETを使用できないことが知られています:Windows XP SP1 [ b ]およびそれ以前のWindowsバージョン、Linuxカーネル2.6より前のバージョン[ c ]
HPET を使用できることが知られているオペレーティングシステムは次のとおりです。Windows XP SP3、[ d ] Windows Server 2003 SP2、Windows Server 2008、Windows Server 2008 R2、Windows Vista、Windows 7 、 OS Xの x86 ベースバージョン、2.6 カーネル (以降) を使用するLinuxオペレーティングシステム、 FreeBSD [ 5 ]およびOpenSolaris。
LinuxカーネルはHPETをクロックソースとして使用することもできます。Red Hat MRGバージョン2のドキュメントには、オーバーヘッドがはるかに低いためTSCが推奨クロックソースであると記載されていますが、フォールバックとしてHPETも使用されます。その環境で1000万イベントカウントのベンチマークを実行したところ、TSCは約0.6秒、HPETは12秒強、ACPI Power Management Timerは約24秒かかりました。[ 6 ]
2019年に、不安定性のため、一部のIntel CPU( Coffee Lake )上で動作する新しいLinuxカーネルでHPETをブラックリストに登録することが決定されました。 [ 7 ]
HPETは、カウントダウンしてゼロになり、1回の割り込みを発生させて停止するワンショットデバイスではなく、カウントアップし続ける連続実行タイマーです。HPETは、実際のタイマー値とプログラムされたターゲット値を「以上」ではなく「等しい」で比較するため、コンパレータ値がチップのレジスタに書き込まれる時点でターゲット時間が既に経過している場合、割り込みを見逃す可能性があります。[ 8 ]このような場合、意図した割り込みを見逃すだけでなく、実際にはかなり先の未来(約232または264カウント)に設定されます。[ 9 ]実行時間に厳密な上限がないマスク不可能な割り込み(システム管理割り込み(SMI)など)が存在する場合、この競合状態は、セットアップ後にタイマーの時間のかかる再チェックを必要とし、完全に回避することは困難です。一部のチップセットのように、コンパレータ値がタイマーとすぐに同期されず、1または2ティック遅れる場合は、困難がさらに悪化します。[ 8 ]
上記で説明した競合状態に加えて、VMwareのドキュメントには他にもいくつかの欠点が挙げられています。「仕様では、タイマーが特に細かい粒度であること、ドリフトが少ないこと、または読み取りが速いことは要求されていません。一般的な実装では、カウンタを約18MHzで動作させ 、HPETの読み取りにはACPIタイマーとほぼ同じ時間(1~ 2μs)が必要です。周期レジスタが800ppm以上ずれている実装も確認されています。」[ 9 ]