Windows system timer tool что это
Период таймера Windows по умолчанию составляет 15.6 мс – он тикает 64 раза в секунду. Когда программа увеличивает частоту таймера, растет потребление энергии, что сказывается на расходе батареи. При этом также расходуется вычислительная мощность компьютера, и даже больше, чем я думал – то есть компьютер начинает работать медленнее! Вот почему в течение многих лет Microsoft настоятельно не рекомендует разработчикам поднимать частоту таймера.
Почему же тогда почти каждый раз, когда я вижу разгон таймера, он вызван программой от Microsoft?
Узнать текущую частоту таймера Windows довольно просто с помощью утилиты clockres от sysinternals.
Maximum timer interval: 15.600 ms
Minimum timer interval: 0.500 ms
Current timer interval: 1.000 ms
Для увеличения времени работы компьютера от батарей текущий период таймера (который может быть изменен функцией timeBeginPeriod) должен быть равен 15.6 мс; но, как вы видите выше, какая-то программа изменила его на 1 мс, что эквивалентно дополнительным 936 тикам в секунду.
Поиск виновного – WPF
Процесс поиска виновного в увеличении частоты не так очевиден, но все-таки довольно прост. В командной строке администратора наберем
powercfg -energy duration 5
и в текущем каталоге появится файл energy-report.html, в котором мы, в частности, прочитаем:
Итак, Visual Studio 11, посредством использования WPF, запросила интервал в 1 мс, что и указано в отчете посредством несколько сбивающей с толку единицы измерения, равной 100 нс. Это известная проблема, связанная с WPF; все версии Visual Studio ведут себя так время от времени и, по-видимому, любое приложение, использующее WPF, может стать источником проблемы. Увеличение частоты может иметь смысл, когда программа пытается поддерживать постоянный фрейм рейт вывода, однако это не оправдывает WPF, поскольку она сохраняет высокую частоту таймера даже в том случае, когда никакой анимации не происходит.
Поиск виновного – SQL сервер
Другой процесс, часто виновный в увеличении частоты на моем компьютере – sqlservr.exe. Думаю, что он был установлен Visual Studio, но не уверен в этом, как не уверен, используется он или нет. В любом случае, SQL сервер не должен повышать частоту таймера; если таким образом предполагается повысить производительность приложения, то это больше похоже на костыль. И, как в случае с WPF, увеличение частоты нужно только тогда, когда сервер занят обработкой данных, а не постоянно.
Platform Timer Resolution:Outstanding Timer Request
A program or service has requested a timer resolution smaller than the platform maximum timer resolution.
Requested Period 10000
Requesting Process ID 2384
Requesting Process Path \Device\HarddiskVolume1\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Binn\sqlservr.exe
Поиск виновного – quartz.dll
У меня нет соответствующей записи из отчета powercfg, но C:\Windows\System32\quartz.dll является еще одним источником проблем с частотой таймера. Я даже толком не знаю, что такое этот Quarts (ну а мы-то знаем, что это не что иное, как Microsoft DirectShow – прим. пер.), но замечал, что иногда он расходует энергию зря.
Поиск виновного – Chrome
Обычно виновными становятся продукты Microsoft, однако к ним в компанию я добавляю еще Google Chrome. Когда я запускаю Chrome он постоянно увеличивает частоту таймера 1000 Гц, даже в том случае, когда компьютер работает от батареи, а я просматриваю простую HTML страницу. Привожу скриншот, фиксирующий преступление Chrome.
Поиск виновного – svchost.exe
Иногда svchost.exe увеличивает частоту таймера до 100 Гц. Это, конечно, не так страшно, как 1000 Гц, но все-таки раздражает. Особенно печально то, что я не могу определить, какой именно сервис это делает.
Общая трагедия – побеждает максимальная частота
Таймер Windows является глобальным ресурсом, он тикает с одинаковой частотой для всей системы целиком. Получается, что если какая-то программа увеличивает частоту таймера, то это сказывается на поведении всей системы.
Когда процесс вызывает функцию timeBeginPeriod, этот запрос частоты остается в силе до тех пор, пока не будет принудительно отменен с помощью timeEndPeriod или до конца работы приложения. Большинство программ (включая и мои тестовые, приведенные ниже) никогда не вызывают timeEndPeriod, полагаясь на системные средства очистки Windows. Это работает и вполне разумно для приложений, которым необходима повышенная частота таймера на всем протяжении исполнения. В противном случае хорошей идеей будет использование timeEndPeriod. По рекомендации Microsoft к приложениям второго вида относятся проигрыватели видео в режиме паузы и свернутые в трей игры. Сюда же можно включить веб-браузеры, которые в текущий момент не требуют высокой частоты таймера или при работе от батареи.
Так ли это важно?
Моим основным компьютером является ноутбук. Каждый день я использую его в автобусе и предпочитаю тратить батарею на что-то полезное, нежели чем на ненужные обращения к процессору 1000 раз в секунду.
Microsoft считает, что это важно. Они говорят: «нашей позицией остается последовательное улучшение энергоэффективности Windows ПК» и все-таки, даже 4 года спустя, сами, похоже, не исполняют свои собственные указания и не обращают внимания на свои же предупреждения: «некоторые приложения уменьшают период таймера до 1 мс, что приводит к сокращению времени работы мобильной системы на 25%».
Удобным способом измерения потребленной энергии является утилита Intel Power Gadget. На поддерживаемых процессорах Intel она покажет мощность, потребляемую упаковкой процессора в реальном времени с точностью до 0,01 Вт. На моем ноутбуке на платформе Sandy Bridge утилита показывает прирост в 0,3 Вт при повышении частоты таймера, что составляет почти 10% от стандартного потребления упаковкой процессора; применительно ко всей системе процент, конечно, будет меньше.
Увеличение на 0,3 Вт может выглядеть не таким большим, но есть пара моментов, заставляющих воспринимать его серьезно. Во-первых, если ваша программа работает, скажем, на 33 миллионах компьютеров (для Chrome это, наверное, даже заниженная оценка), увеличение частоты таймера приведет к потере примерно 10 МегаВатт энергии. Во-вторых, важность проблемы со временем будет только возрастать. Новые процессора с улучшенным объединенным таймером будут затрачивать на учащенные вызовы еще больше вычислительных мощностей.
Быстрые таймеры ухудшают производительность
Исполнение прерываний отнимает некоторую часть ресурсов компьютера, поэтому увеличение их количества в единицу времени должно несколько замедлить скорость его работы. Я проверил эту теорию, написав тестовую программу, крутящую циклы активности и докладывающую каждую секунду скорость своего исполнения. Во время работы программы я изменил частоту таймера, чтобы посмотреть его влияние на производительность.
Влияние было, причем существенное.
Я проделал быстрые тесты на двух компьютерах, так что точные цифры не стоит воспринимать слишком серьезно. Кроме того, они наверняка сильно зависят от аппаратной платформы, нагрузки и т.д. Однако результаты явно показали влияние ускорения таймера на производительность, оно составляет 2,5-5% — это больше, чем я предполагал. Степень замедления достаточно велика, чтобы заподозрить традиционный подход – повышение частоты таймера для увеличения производительности приложения – в контр-продуктивности.
Увеличение частоты таймера Windows не приводит ни к чему хорошему. При этом зря расходуется энергия и замедляется компьютер. Практика применения его во всех без разбора программах, висящих часами без активности, должна быть прекращена.
Вот результаты работы моей тестовой программы в графическом формате
20-секундный период по середине, где производительность неожиданно падает, совпадает с увеличением частоты таймера. Похожие результаты я получил во всех своих тестах, как при питании от батареи, так и от сети
Исходный код
Поскольку наука не делается без раскрытия исходного кода, привожу код своей тестовой программы.
А вот программа, повышающая частоту таймера на 20 сек.
Не забудьте проверить частоту системного таймера перед запуском теста, иначе вы можете не увидеть разницы.
Отключение таймера HPET
Основная проблема в Windows с которой нам нужно бороться – это использование таймера HPET [?] , что уже создаёт лишнюю абстракцию, т.к. это является заменой стандартного таймера RTC [?] или того же HPET (реализаций много, это не так важно), который уже встроен во все современные материнские платы и является аппаратным. В этом и кроется проблема – Windows всё равно тянет одеяло на себя и использует свой программный таймер, так или иначе.
Изначально идея нового таймера здравая и хорошая – добиться более высокой точности для управления прерываниями [?] для мультимедийных программ, хотя у него и намного больше применений, в том числе он отвечает за счёт времени и многое другое. Но мы бы тут не собрались, если бы он работал так как задумывалось. Проблем таймер создаёт достаточно [Проблемы с HPET] . Если вкратце, то значение выдаваемое таймером должно быть строго фиксированным, но в виду своей странной реализации оно имеет плавающее значение и периодические меняется, из-за чего прерывания происходят в разное время, что и вызывает запоздания, а они в свою очередь микрофризы и микролаги, особенно это заметно при использовании игр или высоконагруженных приложений (рендер, обработка фотографий и т.п.).
Некоторые мультимедийные программы, а так же игры могут сами фиксировать данный параметр для увеличения плавности [?] , поэтому мы его сами зафиксируем на минимально возможном значении в 0.5ms , для всей системы в том числе.
‼️ Ни в коем случае не отключайте данный таймер в BIOS – там он должен быть включён для корректной работы системы в целом. В новых версиях BIOS подобная настройка включена по-умолчанию и зачастую её изменение не возможно. Подробную информацию как изменить параметры в BIOS можно найти в руководстве к материнской плате или в интернете.
Для того чтобы отключить HPET в Windows необходимо использовать встроенную утилиту bcdedit . Но сперва нам надо убедиться, что таймер в Windows активен:
Если у вас нет значений useplatformtick и disabledynamictick или они установлены как No , то первым шагом для нас будет их отключение:
Пример правильного отключения таймера HPET в Windows:
Теперь, отключив таймер в Windows, нам надо зафиксировать его в значении 0.5ms – для этого необходимо использовать утилиту Intelligent Standby List Cleaner [скачать] . Здесь можно увидеть, что значение нашего таймера Current timer resolution постоянно изменяется, что не есть хорошо и именно это нам надо исправлять.
Пример не настроенного таймера в Intelligent Standby List Cleaner :
Для правильной настройки необходимо установить следующие параметры:
- Start ISCL minimized and auto-Start monitoring включено
- Launch ISCL on user logon (TaskSheduler) включено
- Enable custom timer resolution включено
- Wanted timer resolution установлено в 0.50
Так же здесь можно настроить очищение системного кэша памяти [?] . Для этого необходимо изменить параметр Free memory is lower than , который отвечает за минимальное значение свободной памяти – оптимальным значением является размер вашей памяти разделённый на 2, после достижения которого кэш памяти будет очищен. Параметр The list size is at least отвечает за минимальный размер кэшированный памяти и его рекомендуется оставлять дефолтным - равным 1024 Mb .
Если лень считать
⚠️ Во избежание дополнительных микрофризов при очищении кэша памяти, если у вас её мало или же её очень активно используют программы, данную настройку лучше протестировать с разными параметрами и найти оптимальную для вашего сценария использования.
После настройки надо нажать Start и проверить зафиксирован ли таймер – значение Current timer resolution должно быть строго равно 0.5ms и не изменяться. Значение может обновится с задержкой!
Пример правильной настройки Intelligent Standby List Cleaner :
Включение MSI mode
А зачем нам ещё включать какой-то MSI mode [?] ? Всё очень просто, если раньше на одно устройство выделялось всего 4 прерывания [Страдания по IRQ] , то с помощью MSI стало возможным увеличить их до 32, что значительно ускоряет общение между устройствами.
Почти все последние драйверы, от нормальных производителей, используют изначально режим прерывания MSI , тем более это обязательное условие для PCI Express железок. Но для ускорения всей системы так же не лишним будет включение MSI и для USB Host Controller .
Для включения MSI mode мы будем использовать утилиту MSI Util v2 [скачать] . Ищем здесь нашу видеокарту и USB Host Controller (если по названию не получается найти, то в строке с именем так же указан Device ID ). Ставим галочку в столбце MSI , так же меняем Interrupt priority на Hight , после чего жмём кнопку Apply .
Пример настройки MSI с помощью MSI Util v2 :
‼️ Нельзя устанавливать использование MSI mode для всех ваших устройств, иначе устройства могут работать не корректно.
⚠️ Данная настройка сбрасывается на дефолтное значение после обновления драйвера nVidia!
Продолжая тему прерываний, далее нам необходимо настроить приоритет прерываний для конкретно заданных устройств – этим в Windows занимается IRQL [?] . Проблема приоритизации всегда имеет место быть, т.к. каждое устройство считает себя важней остальных и это порождает некоторые проблемы [Проблемы IRQL] .
В качестве имени параметра мы используем IRQ***Priority , где *** надо заменить на IRQ (несколько цифр) нашей видеокарты и USB Host Controller .
✨ Для видеокарты рекомендуется ставить значение равным 1 , для USB Host Controller – значение 2 [Приоритеты IRQ] .
💡 Для дальнейшей настройки необходимо ознакомиться c Работа с реестром.
Следующим шагом после настройки приоритетов IRQL [?] необходимо указать приоритет для каких сервисов (в нашем случае драйверов) необходимо выполнять прерывания в первую очередь. Когда происходит прерывание, Windows, используя IRQL для определения приоритета прерывания, проверяет может ли прерывание обслуживаться в данный момент или нет, если условие выполняется, то приоритет потока начинает его выполнение. Всё что ниже по приоритету – ставиться в очередь. Таким образом мы зафиксируем критически важные сервисы, прерывания от которых необходимо обрабатывать в первую очередь.
✨ В качестве параметра установите значения равным 15 ( f ) (что соответствует Hight ), если система работает стабильно, то можно повысить приоритет установив параметр равным 31 ( 1f ) (что соответствует Realtime ) [Процессы и потоки в Windows] для nvlddmkm .
Распараллеливание драйверов по ядрам
Самое сложное осталось позади и теперь мы будет освобождать первое ядро, куда Windows зачем-то добавляет почти все драйверы. Этим мы с одной стороны разгрузим ядро, а с другой так же уменьшим задержки.
Для этого нам понадобиться утилита Interrupt Affinity Policy Tool [скачать] .
Пример списка устройств в утилите Interrupt Affinity Policy Tool :
В этом списке надо найти свою видеокарту и USB Host Controller (название может не соответствовать, поэтому искать лучше по полю Location Info ), нажать Set Mask и выбрать ядро на которое будет назначен драйвер. Выбирать надо на любое ядро отличное от первого.
⚠️ На CPU, где включен Hyper-Threading [?] / SMT [?] , ядра и потоки в программе чередуются – CPU 0 - Ядро 1, CPU 1 - Поток 1, CPU 2 - Ядро 2, CPU 3 - Поток 2 и т.д., соответственно, чтобы выбрать третье ядро надо указать CPU 4 и CPU 5 . На CPU без Hyper-Threading / SMT ядра, само собой, указаны без потоков.
‼️ Нельзя переносить все драйверы на другие ядра, этим вы лишь можете добиться появления BSOD [?] !
⚠️ Данная настройка сбрасывается на дефолтное значение после обновления драйвера nVidia!
Читайте также: