Таймер слияния до Windows 7

В Windows 7 и Windows 8 есть поддержка объединения таймеров, см., Например, следующее: Объединение таймеров в.net
Windows 7 имеет функцию SetWaitableTimerEx о котором утверждается, что он поддерживает объединение здесь и здесь.
Windows 8 имеет дополнительно функцию SetCoalescableTimer который поддерживает объединение в соответствии с MSDN.


Так много разговоров о слиянии таймеров в Windows 7 и Windows 8. Но тогда кажется, что это, возможно, было реализовано уже ранее. Это так?


Во-первых, правильно ли, что SetThreadpoolTimer доступно, так как Vista обеспечивает объединение таймеров под Vista. Или он предлагает только интерфейс и фактически осуществляет объединение только начиная с Windows 7?
Из "Таймеров пула потоков и ввода / вывода" я могу прочитать, что

"На самом деле это функция, которая влияет на энергоэффективность и помогает снизить общее энергопотребление. Она основана на методике, называемой объединением таймеров".

Это предложение верно для всех версий Windows, которые поддерживают SetThreadpoolTimer функционировать?


Во-вторых, теперь, когда я начал задаваться вопросом. я могу увидеть это timeSetEvent доступно, так как XP имеет параметр с именем uResolution, Изменяет ли этот параметр разрешение глобального таймера следующим образом timeBeginPeriod В течение времени ожидания события таймера или это влияет только на этот конкретный таймер, обеспечивая также объединение таймера?


Наконец, существуют ли дополнительные или альтернативные функции, которые обеспечивают объединение таймеров в Windows XP или Vista?

1 ответ

Решение

Несколько слов в общем:

Объединение таймеров позволяет сократить количество прерываний. Приложениям разрешено указывать допуск для их требований к времени. Это позволяет операционной системе "пакетно" прерывать с несколькими последствиями:

  • количество прерываний может быть уменьшено. (+)
  • количество переключений контекста может быть меньше. (+)
  • энергопотребление может быть уменьшено. (+)
  • большая часть операций, возможно, должна быть сделана в тех пакетных прерываниях (-)
  • Планировщик может планировать большое количество процессов в это время (-)
  • разрешение во времени хуже (-)

Windows, как и другие операционные системы, основанные на прерываниях, всегда "пакетировали" синхронизированные события. Все, что настроено на выполнение в определенное время, зависит от времени истечения срока действия с помощью interrut. Следовательно, события объединяются с прерыванием. Гранулярность этой схемы определяется частотой прерывания. Необходимо прочитать для тех, кто заинтересован в объединении таймеров: MSDN: Объединение таймеров Windows.

Из соображений производительности следует приложить все усилия, чтобы максимально сократить количество прерываний. К сожалению, многие пакеты устанавливают очень высокое разрешение системного таймера, например, с помощью интерфейса мультимедийного таймера. timeBeginPeriod / timeEndPeriod или базовый API NtSetTimerResolution, Как упоминал Ганс: "Chrome" является хорошим примером того, как использование этих функций может быть сильно преувеличено.


Во-вторых, теперь, когда я начал задаваться вопросом... timeSetEvent является одной из функций мультимедийного таймера. Оно использует timeBeginPeriod под капотом.

И он использует его плохо: он устанавливает разрешение системного таймера так, чтобы оно соответствовало uResolution настолько хорошо, насколько это возможно в пределах разрешений таймера, доступных на исполняющей платформе. При больших значениях uDelay он может ожидать при низком разрешении, пока не приблизится к истечению задержки, и только затем повысить разрешение системного таймера, но он устанавливает разрешение таймера на весь период ожидания на указанное значение uResolution. Это больно, зная, что высокое разрешение будет применяться и для длительных задержек. Однако функции мультимедийного таймера не предлагаются для использования с большими задержками. Но устанавливать разрешение снова и снова не очень хорошо (см. Примечания ниже).

Резюме по timeSetEvent: Эта функция не выполняет ничего похожего на объединение, а наоборот: увеличивает количество прерываний; в этом смысле он распределяет события по большему количеству прерываний, он "распаковывает" их.

SetThreadpoolTimer впервые представляет идею "пакетирования" событий. Это было вызвано главным образом из-за растущих жалоб на время автономной работы ноутбуков с Windows. SetWaitableTimerEx продвинул эту стратегию дальше и SetCoalescableTimer это самый последний API для доступа к таймерам объединения. Последний представляет TIMERV_DEFAULT_COALESCING и TIMERV_NO_COALESCING, о которых стоит задуматься, поскольку они позволяют игнорировать определенные факты.


Пользуясь возможностью сделать некоторые заметки о разрешении системного таймера:

Изменение разрешения системного таймера имеет больше последствий, чем просто увеличение частоты прерываний. Некоторые эффекты, связанные с использованием timeBeginPeriod / NtSetTimerResolution:

  1. Изменения частоты прерываний
  2. Квантовые изменения потока (временной отрезок потока) (!)
  3. Икоты системного времени ( MSDN: "... частые звонки могут существенно повлиять на системные часы")
  4. Сбой, когда активна системная настройка времени (SetSystemTimeAdjustment)

Пункт 3. был частично решен в Windows 7, а пункт 4. - только в Windows 8.1. Икоты системного времени могут быть такими же большими, как минимальное поддерживаемое разрешение таймера (15,625 мс на типичных системах), и они накапливаются, когда timeBeginPeriod / NtSetTimerResolution часто. Это может привести к значительному скачку при попытке настроить системное время в соответствии с заданием NTP. NTP-клиенты должны работать с высоким разрешением таймера, чтобы получить разумную точность при работе в версии Windows

Наконец, Windows сама изменяет разрешение системного таймера всякий раз, когда видит преимущества для этого. Количество поддерживаемых разрешений таймера зависит от используемого оборудования и версии Windows. Список доступных разрешений может быть получен путем сканирования через них, вызывая timeBeginPeriod с увеличивающимися периодами, сопровождаемыми вызовом NtQueryTimerResolution. Некоторые из поддерживаемых разрешений могут "не нравиться" Windows на определенных платформах и модифицироваться для лучшего соответствия потребностям Windows. Пример: XP может изменить разрешение, установленное пользователем, от ~ 4 мс до 1 мс после короткого промежутка времени на определенных платформах. Отдельные версии Windows < 8.1 действительно изменяют разрешение таймера в непредсказуемое время.

Если требуется, чтобы приложение было полностью независимым от этих артефактов, оно должно самостоятельно получить максимально возможное разрешение. Таким образом, приложение доминирует над общесистемным разрешением, и оно не должно беспокоиться о других приложениях или об изменении разрешения таймера ОС. Более современные платформы поддерживают разрешение таймера 0,5 мс. timeBeginPeriod не позволяет получить это разрешение, но NtSetTimerResolution делает. Здесь я описал, как использовать NtSetTimerResolution для получения разрешения 0,5 мс.

Потребление энергии в таких условиях может возрасти, но это плата за надежное разрешение. Стоимость энергии для контекстного переключателя обычно составляет от 0,05 мДж до 0,2 мДж на современном оборудовании (Кто-нибудь оценивал общее количество переключений контекста в мире в год?). Windows сокращает квант потока (временной интервал) до прибл. 2/3, когда разрешение таймера установлено на максимум. Следовательно, энергопотребление увеличивается примерно на 30%!

Другие вопросы по тегам