У меня есть система HP ProLiant DL380 G7, использующая 2 6-ядерных процессора с включенной Hyper-threading, всего 24 логических процессора (как видно из Windows).
При запуске нашего приложения общая загрузка ЦП системы хорошая, но одна из 24 CUP привязана к 100%:
Редактировать: Это данные PerfMon для системного процесса за это время и для процессора с высокой степенью использования:
Это нормально? Если нет, есть ли способ определить, какие процессы используют этот логический ЦП? Windows PerfMon, ResMon, диспетчер задач и обозреватель процессов не помогли, кроме определения того, что ЦП загружен на 100%.
Покажите столбец «Процессорное время» на вкладке «Подробности» в «Диспетчере задач» и найдите процесс с постоянно увеличивающимся счетчиком процессорного времени. Это ваш клиновидный процесс. Он должен постоянно использовать около 4,17% ЦП.
Как уже отмечали другие, из этого снимка экрана видно, что процессор, который так много работает, проводит все свое время в режиме ядра. (Красный цвет.)
Запустите Powershell от имени администратора, введите:
Get-Process | Select Name, PrivilegedProcessorTime | `
Sort-Object PrivilegedProcessorTime -Descending
Процесс в верхней части списка - это процесс, который в настоящее время использует большую часть процессорного времени в режиме ядра. Если этот процесс не «Система», то вы только что выяснили, какой процесс пользовательского режима вызывает эту загрузку ЦП. Если процесс с наивысшим временем привилегированного процессора - это система, а я подозреваю, что это так, то это немного сложнее.
Откройте Process Explorer. При желании настройте сервер символов. Убедитесь, что вы работаете с полным повышением уровня UAC. Щелкните правой кнопкой мыши «процесс» системы и перейдите в Свойства. Затем перейдите на вкладку Темы. Отсортируйте потоки по загрузке ЦП. Здесь должен быть поток, который вызывает всю эту работу режима ядра. Если вы посмотрите на модуль, указанный в разделе «Начальный адрес», он должен дать вам представление о том, с чем связана работа. Например, если это NDIS.sys, это драйвер сетевого интерфейса. Если вы настроили сервер символов, вы должны увидеть имя функции в модуле (если модуль не принадлежит Microsoft), иначе вы просто увидите числовое смещение от начального адреса модуля.
В качестве альтернативы можно использовать Xperf из Windows Performance Toolkit для профилирования прерываний, DPC и т. Д.
xperf -on PROC_THREAD+LOADER+DPC+INTERRUPT
и остановить запись с помощью xperf -d logfile.etl
Xperf заменяет старый инструмент Kernrate и может предоставить вам очень подробные данные.
Когда ЦП выполняет работу в режиме ядра, он в основном выполняет процедуры обслуживания прерываний. (ISR) Когда происходит прерывание, работа в пользовательском режиме на этом процессоре приостанавливается, и ЦП запускает ISR, зарегистрированную для этого прерывания. Если вы обнаружите, что ваш ЦП тратит чрезмерное количество времени на эти прерывания, это обычно указывает на неисправный драйвер устройства, который необходимо обновить.
Что меня беспокоит (без каламбура) в этом сценарии, так это то, что кажется, что любой поток ядра, который это делает, кажется аффинитизированный к этому ядру. Интересно, почему диспетчер, кажется, только планирует запуск потока на этом, казалось бы, произвольном ядре. Так что у меня есть ощущение, что нам нужно найти того, кто написал этот драйвер устройства, и показать им, как выполнять многопоточные DPC, а не явно устанавливать привязку к потокам ядра и т. Д.
Кажется, что это все время ядра, могут быть прерывания, они могут обрабатываться только одним процессором.
Найдите процесс с постоянной загрузкой ЦП ~ 4% (= 1/24 всего доступного ЦП). Это должен быть тот, который постоянно занимает один процессор.