Таймеры High-Resolution
Начиная с Windows 8.1, драйверы могут использовать подпрограммы Таймера ExXxx для управления таймерами с высоким разрешением. Точность таймера с высоким разрешением ограничивается только максимальным поддерживаемым разрешением системных часов. В отличие от этого, таймеры, которые ограничены разрешением системных часов по умолчанию, значительно менее точны.
Однако для таймеров с высоким разрешением требуется, чтобы прерывания системных часов (по крайней мере временно) происходили с более высокой скоростью, что, как правило, приводит к увеличению энергопотребления. Таким образом, драйверы должны использовать таймеры с высоким разрешением, только если точность таймера важна, и использовать таймеры разрешения по умолчанию во всех остальных случаях.
Чтобы создать таймер с высоким разрешением, драйвер WDM вызывает подпрограмму ExAllocateTimer и устанавливает флаг EX_TIMER_HIGH_RESOLUTION в параметре Attributes . Когда драйвер вызывает подпрограмму ExSetTimer для задания таймера с высоким разрешением, операционная система при необходимости увеличивает разрешение системных часов, чтобы время истечения срока действия таймера точнее соответствовало номинальному времени истечения срока действия, указанному в параметрах DueTime и Period .
Драйвер Kernel-Mode Driver Framework (KMDF) может вызвать метод WdfTimerCreate , чтобы создать таймер с высоким разрешением. В этом вызове драйвер передает указатель на структуру WDF_TIMER_CONFIG в качестве параметра. Чтобы создать таймер с высоким разрешением, драйвер устанавливает для элемента UseHighResolutionTimer этой структуры значение TRUE. Этот элемент является частью структуры, начиная с Windows 8.1 и KMDF версии 1.13.
Управление точностью таймера
Например, для Windows, работающей на процессоре x86, интервал по умолчанию между тактами системных часов обычно составляет около 15 миллисекунд, а минимальный интервал между тактами системных часов составляет около 1 миллисекунды. Таким образом, срок действия таймера разрешения по умолчанию (который создается ExAllocateTimer , если флаг EX_TIMER_HIGH_RESOLUTION не задан) можно контролировать только в пределах около 15 миллисекундах, но время окончания срока действия таймера с высоким разрешением можно контролировать до миллисекунда.
Если драйвер указывает относительное время истечения срока действия для таймера разрешения по умолчанию, срок действия таймера может истечь до 15 миллисекундах раньше или позже указанного времени истечения срока действия. Если драйвер указывает относительное время истечения срока действия для таймера с высоким разрешением, срок действия таймера может истечь примерно через миллисекунды после указанного срока действия, но он никогда не истечет раньше. Дополнительные сведения о связи между разрешением системных часов и точностью таймера см. в разделе Точность таймера.
Если таймеры с высоким разрешением не заданы, операционная система обычно запускает системные часы по умолчанию. Однако если задан один или несколько таймеров с высоким разрешением, операционной системе может потребоваться запустить системные часы с максимальной скоростью по крайней мере за часть времени до истечения срока действия этих таймеров.
Чтобы избежать неоправданного увеличения энергопотребления, операционная система запускает системные часы с максимальной скоростью только в том случае, если это необходимо для удовлетворения требований таймеров с высоким разрешением. Например, если таймер с высоким разрешением является периодическим и его период охватывает несколько тактов системных часов по умолчанию, операционная система может запускать системные часы с максимальной скоростью только в той части периода таймера, который непосредственно предшествует каждому истечению срока действия. Для остальной части периода таймера системные часы работают по умолчанию.
Чтобы предотвратить чрезмерное энергопотребление, драйверам следует избегать установки длительного таймера с высоким разрешением значения, которое меньше интервала по умолчанию между тактами системных часов. В противном случае операционная система вынуждена непрерывно запускать системные часы с максимальной скоростью.
Начиная с Windows 8, драйвер может вызывать подпрограмму ExQueryTimerResolution, чтобы получить диапазон разрешений таймера, поддерживаемых системными часами.
Сравнение с ExSetTimerResolution
Начиная с Windows 2000, драйвер может вызывать подпрограмму ExSetTimerResolution , чтобы изменить интервал времени между последовательными прерываниями системных часов. Например, драйвер может вызвать эту подпрограмму, чтобы изменить системные часы с частоты по умолчанию на максимальную, чтобы повысить точность таймера. Однако использование ExSetTimerResolution имеет несколько недостатков по сравнению с использованием таймеров с высоким разрешением, созданных ExAllocateTimer.
Во-первых, после вызова ExSetTimerResolution для временного увеличения частоты системных часов драйвер должен вызвать ExSetTimerResolution во второй раз, чтобы восстановить системные часы до частоты по умолчанию. В противном случае таймер системных часов непрерывно создает прерывания с максимальной скоростью, что может привести к чрезмерному энергопотреблению.
Во-вторых, драйвер, использующий подпрограмму ExSetTimerResolution , не может оптимизировать временное использование более высокой системной частоты так же эффективно, как это делает операционная система для таймеров с высоким разрешением. Таким образом, системные часы тратят больше времени на выполнение с максимальной скоростью, чем это строго необходимо.
В-третьих, если несколько драйверов одновременно используют ExSetTimerResolution для повышения точности таймера, системные часы могут работать с максимальной скоростью в течение длительного времени. В отличие от этого, операционная система глобально координирует работу нескольких таймеров с высоким разрешением, чтобы системные часы запускались с максимальной скоростью только в том случае, если это необходимо для удовлетворения временных требований этих таймеров.
Наконец, использование ExSetTimerResolution изначально менее точно, чем использование таймера с высоким разрешением. После того как драйвер вызывает ExSetTimerResolution , чтобы увеличить системные часы до максимальной скорости, которая обычно составляет около галочки в миллисекундах, драйвер может вызвать подпрограмму , например KeSetTimerEx , чтобы задать таймер. Если в этом вызове драйвер указывает относительное время истечения срока действия, срок действия таймера может истечь примерно на миллисекунды раньше или позже указанного срока действия. Однако если для таймера с высоким разрешением задано относительное время истечения срока действия, срок действия таймера может истечь примерно на миллисекунды позже указанного времени, но он никогда не истечет раньше.