Windows CPU Scheduler - очень высокое время ядра
Мы пытаемся понять, как работает планировщик ЦП Windows, чтобы оптимизировать наши приложения для достижения максимально возможного соотношения инфраструктуры и реальной работы. В xperf есть некоторые вещи, которые мы не понимаем и хотели бы попросить сообщество пролить свет на то, что на самом деле происходит. Сначала мы начали исследовать эти проблемы, когда получили сообщения о том, что некоторые серверы были "медленными" или "не отвечающими".
Исходная информация
У нас есть сервер Windows 2012 R2, на котором работает инфраструктура промежуточного программного обеспечения со следующими характеристиками.
Мы обнаружили, что 30% процессорного времени теряется на ядре, поэтому мы начали копать глубже.
Сервер выше выполняет "хост" ~500 процессов (как службы Windows), каждый из этих процессов "хоста" имеет внутренний цикл while с задержкой ~250 мс (чёрт!), И каждый из этих процессов "хоста" может иметь ~1..2 "дочерние" процессы, выполняющие реальную работу.
Несмотря на наличие бесконечного цикла с задержкой 250 мс между итерациями, реальная полезная работа для запуска "основного" приложения может появляться только каждые 10..15 секунды. Так что для ненужных циклов тратится много циклов.
Мы понимаем, что дизайн "основного" приложения является неоптимальным, если не сказать больше, применительно к нашему сценарию. Приложение изменяется на модель, основанную на событиях, которая не требует цикла, и поэтому мы ожидаем значительного сокращения времени "ядра" в графике загрузки ЦП.
Однако, пока мы изучали эту проблему, мы провели некоторый xperf-анализ, в ходе которого было задано несколько общих вопросов о планировщике ЦП Windows, для которых мы не смогли найти какое-либо четкое / краткое объяснение.
Что мы не понимаем
Ниже приведен скриншот из одного из сеансов xperf.
Вы можете увидеть из "Использование ЦП (Точное)", что
Временные интервалы 15 мс, большинство из которых используются недостаточно. Коэффициент использования этих ломтиков составляет ~35-40%. Таким образом, я предполагаю, что это, в свою очередь, означает, что процессор используется примерно в 35-40% времени, но производительность системы (скажем, наблюдаемая при случайных манипуляциях с системой) действительно вялая.
При этом мы имеем "таинственные" 30% затрат времени ядра, судя по графику загрузки ЦП диспетчера задач.
Некоторые процессоры, очевидно, используются для всего среза 15 мс и выше.
Вопросы
Что касается планирования ЦП Windows в многопроцессорных системах:
- Что вызывает 30% стоимости ядра? Переключение контекста? Что-то другое? На что следует обращать внимание при написании приложений, чтобы снизить эту стоимость? Или даже - добиться идеального использования с минимальными затратами на инфраструктуру (в многопроцессорных системах, где число процессов превышает количество ядер)
- Что это за 15 мсек?
- Почему загрузка ЦП имеет пробелы в этих срезах?
1 ответ
Чтобы выявить проблемы использования ЦП, вы должны использовать Event Tracing для Windows (ETW) для сбора данных выборки ЦП (не точный, это полезно для обнаружения зависаний).
Для захвата данных установите Windows Performance Toolkit, который является частью Windows SDK.
Теперь беги WPRUI.exe
, Выбрать First Level
, под Resource выберите использование CPU и нажмите на start.
Теперь запишите 1 минуту использования процессора. Через 1 минуту нажмите Сохранить.
Теперь проанализируйте сгенерированный файл ETL с помощью анализатора производительности Windows, перетащив CPU Usage (sampled)
график к analysis pane
и заказать столбцы, как вы видите на картинке:
Внутри WPA загрузите символы отладки и разверните стек процесса SYSTEM. В этой демонстрации загрузка ЦП происходит от драйвера nVIDIA.