High-Resolution Timer

Ab Windows 8.1 können Treiber die Ex Xxx-Timerroutinen verwenden, um Zeitgeber mit hoher Auflösung zu verwalten. Die Genauigkeit eines Timers mit hoher Auflösung wird nur durch die maximal unterstützte Auflösung der Systemuhr begrenzt. Im Gegensatz dazu sind Timer, die auf die Standardauflösung der Systemuhr beschränkt sind, deutlich weniger genau.

Timer mit hoher Auflösung erfordern jedoch , dass Unterbrechungen der Systemuhr zumindest vorübergehend mit einer höheren Rate auftreten, was den Stromverbrauch tendenziell erhöht. Daher sollten Treiber nur dann hochauflösende Timer verwenden, wenn die Zeitgebergenauigkeit entscheidend ist, und in allen anderen Fällen Timer mit Standardauflösung verwenden.

Um einen Timer mit hoher Auflösung zu erstellen, ruft ein WDM-Treiber die ExAllocateTimer-Routine auf und legt das flag EX_TIMER_HIGH_RESOLUTION im Attributes-Parameter fest. Wenn der Treiber die ExSetTimer-Routine aufruft, um den hochauflösenden Timer festzulegen, erhöht das Betriebssystem bei Bedarf die Auflösung der Systemuhr, sodass die Zeiten, zu denen der Timer abläuft, genauer den nominalen Ablaufzeiten entsprechen, die in den Parametern DueTime und Period angegeben sind.

Ein kmDF-Treiber (Kernel-Mode Driver Framework) kann die WdfTimerCreate-Methode aufrufen, um einen Timer mit hoher Auflösung zu erstellen. In diesem Aufruf übergibt der Treiber einen Zeiger auf eine WDF_TIMER_CONFIG-Struktur als Parameter. Um einen Timer mit hoher Auflösung zu erstellen, legt der Treiber den UseHighResolutionTimer-Member dieser Struktur auf TRUE fest. Dieser Member ist ab version 1.13 von Windows 8.1 und KMDF Teil der -Struktur.

Steuern der Zeitgebergenauigkeit

Für Windows, das auf einem x86-Prozessor ausgeführt wird, beträgt das Standardintervall zwischen Systemuhr-Ticks in der Regel etwa 15 Millisekunden, und das minimale Intervall zwischen Systemuhrtakten beträgt etwa 1 Millisekunde. Daher kann die Ablaufzeit eines Timers mit Standardauflösung (den ExAllocateTimer erstellt, wenn das EX_TIMER_HIGH_RESOLUTION-Flag nicht festgelegt ist) nur auf etwa 15 Millisekunden gesteuert werden, aber die Ablaufzeit eines Timers mit hoher Auflösung kann innerhalb einer Millisekunde gesteuert werden.

Wenn ein Treiber eine relative Ablaufzeit für einen Timer mit Standardauflösung angibt, kann der Timer bis zu etwa 15 Millisekunden früher oder höher als die angegebene Ablaufzeit ablaufen. Wenn ein Treiber eine relative Ablaufzeit für einen Timer mit hoher Auflösung angibt, kann der Timer nach etwa einer Millisekunde nach der angegebenen Ablaufzeit ablaufen, er läuft jedoch nie frühzeitig ab. Weitere Informationen zur Beziehung zwischen Systemuhrauflösung und Timergenauigkeit finden Sie unter Timergenauigkeit.

Wenn keine Zeitgeber mit hoher Auflösung festgelegt sind, führt das Betriebssystem die Systemuhr in der Regel mit der Standardrate aus. Wenn jedoch mindestens ein Timer mit hoher Auflösung festgelegt ist, muss das Betriebssystem die Systemuhr möglicherweise mindestens einen Teil der Zeit mit ihrer maximalen Rate ausführen, bevor diese Zeitgeber ablaufen.

Um einen unnötigen Anstieg des Stromverbrauchs zu vermeiden, führt das Betriebssystem die Systemuhr nur dann mit der maximalen Rate aus, wenn dies zur Erfüllung der Zeitsteuerungsanforderungen von Zeitgebern mit hoher Auflösung erforderlich ist. Wenn ein Timer mit hoher Auflösung z. B. periodisch ist und sein Zeitraum mehrere Standardtakte der Systemuhr umfasst, kann das Betriebssystem die Systemuhr nur in dem Teil des Zeitgeberzeitraums ausführen, der unmittelbar vor jedem Ablauf liegt. Für den rest des Zeitgeberzeitraums wird die Systemuhr mit ihrer Standardrate ausgeführt.

Um einen übermäßigen Stromverbrauch zu vermeiden, sollten Treiber vermeiden, den Zeitraum eines zeitintensiven Timers mit hoher Auflösung auf einen Wert festzulegen, der kleiner als das Standardintervall zwischen Systemuhrtakten ist. Andernfalls wird das Betriebssystem gezwungen, die Systemuhr kontinuierlich mit der maximalen Rate auszuführen.

Ab Windows 8 kann ein Treiber die ExQueryTimerResolution-Routine aufrufen, um den Bereich der Zeitgeberauflösungen abzurufen, die von der Systemuhr unterstützt werden.

Vergleich mit ExSetTimerResolution

Ab Windows 2000 kann ein Treiber die ExSetTimerResolution-Routine aufrufen, um das Zeitintervall zwischen aufeinander folgenden Systemuhrunterbrechungen zu ändern. Beispielsweise kann ein Treiber diese Routine aufrufen, um die Systemuhr von ihrer Standardrate in ihre maximale Rate zu ändern, um die Timergenauigkeit zu verbessern. Die Verwendung von ExSetTimerResolution hat jedoch mehrere Nachteile gegenüber der Verwendung hochauflösender Timer, die von ExAllocateTimer erstellt wurden.

Erstens muss ein Treiber nach dem Aufruf von ExSetTimerResolution , um die Systemuhrrate vorübergehend zu erhöhen, ein zweites Mal ExSetTimerResolution aufrufen, um die Systemuhr auf die Standardrate wiederherzustellen. Andernfalls generiert der Systemuhrtimer kontinuierlich Unterbrechungen mit der maximalen Rate, was zu einem übermäßigen Stromverbrauch führen kann.

Zweitens kann ein Treiber, der die ExSetTimerResolution-Routine verwendet, seine vorübergehende Verwendung höherer Systemtaktraten nicht so effektiv optimieren wie das Betriebssystem für Zeitgeber mit hoher Auflösung. Daher verbringt die Systemuhr mehr Zeit mit der maximalen Rate, als es unbedingt erforderlich ist.

Drittens: Wenn mehrere Treiber gleichzeitig ExSetTimerResolution verwenden, um die Timergenauigkeit zu verbessern, kann die Systemuhr über einen längeren Zeitraum mit ihrer maximalen Rate ausgeführt werden. Im Gegensatz dazu koordiniert das Betriebssystem den Betrieb mehrerer Zeitgeber mit hoher Auflösung global, sodass die Systemuhr nur dann mit der maximalen Rate ausgeführt wird, wenn dies zur Erfüllung der Zeitsteuerungsanforderungen dieser Zeitgeber erforderlich ist.

Schließlich ist die Verwendung von ExSetTimerResolution von Natur aus weniger genau als die Verwendung eines Timers mit hoher Auflösung. Nachdem ein Treiber ExSetTimerResolution aufgerufen hat, um die Systemuhr auf die maximale Rate zu erhöhen, die in der Regel bei einem Tick pro Millisekunde liegt, kann der Treiber eine Routine wie KeSetTimerEx aufrufen, um den Timer festzulegen. Wenn der Treiber in diesem Aufruf eine relative Ablaufzeit angibt, kann der Timer bis zu einer Millisekunde vor oder später als der angegebenen Ablaufzeit ablaufen. Wenn jedoch eine relative Ablaufzeit für einen Timer mit hoher Auflösung angegeben wird, kann der Timer bis zu etwa einer Millisekunde später als die angegebene Ablaufzeit ablaufen, aber er läuft nie frühzeitig ab.