Как следует из названия, я заинтересован в получении тактовых циклов процессора, используемых процессом только в режиме ядра. Я знаю, что есть API под названием «QueryProcessCycleTime», который возвращает часы процессора
циклы, используемые потоками процесса. Но это значение включает циклы, проведенные как в режиме пользователя, так и в режиме ядра. Как я могу получить циклы, проведенные только в режиме ядра? Нужно ли получать это с помощью счетчиков производительности? Если да, какой я должен использовать?
Заранее спасибо за ваши ответы.
Я только что нашел интересную статью, которая описывает почти то, что вы просите. Это на MSDN Internals.
Там пишут, что если вы использовали C # или C ++ / CLI, вы можете легко получить эту информацию из экземпляра System.Diagnostic.Process
класс, указал на правильный PID. Но это даст вам TimeSpan
от PrivilegedProcessorTime
так что «красивое время» вместо «циклов».
Тем не менее, они также указывают, что весь этот .Net-код на самом деле является тонкой оболочкой для неуправляемых API, поэтому вы также можете легко получить его из нативного C ++. Они использовали ILDASM для показа того, что он называет, но изображение отсутствует. Я только что сделал то же самое, и он использует GetProcessTimes
от kernel32.dll
Итак, еще раз, MSDN’инг это — это возвращается LPFILETIME
структур. Итак, снова «красивое время», а не «циклы».
Описание этого метода указывает на то, что если вы хотите получить тактовые циклы, вы должны использовать QueryProcessCycleTime функция. Это на самом деле возвращает количество тактов … но пользовательский режим и режим ядра подсчитываются вместе.
Теперь подводим итоги:
Таким образом, у вас есть почти все необходимое. По простой математике:
u_cycles = u_time * allcycles / (utime+ktime)
k_cycles = k_time * allcycles / (utime+ktime)
Конечно, это будет некоторое приближение из-за округления и т. Д.
Кроме того, здесь есть недочёт: вам нужно вызвать две функции (GetTimes, QueryCycles), чтобы получить всю информацию, поэтому между их показаниями будет небольшая задержка и, следовательно, весь ваш расчет. вероятно, немного поскользнется поскольку целевой процесс все еще выполняется и сжигает время.
Если вы не можете учесть этот (маленький?) Шум в измерении, я думаю, что вы можете обойти его временно суспендирующий процесс:
Я думаю, что это обеспечит согласованность этих двух показаний, но, в свою очередь, каждое такое считывание будет влиять на общую производительность измеряемого процесса, то есть такие вещи, как «время стены», больше не будут измеряться, если вы не примете некоторые поправки для время, проведенное в подвешенном состоянии ..
Возможно, есть какой-то лучший способ получить отдельные тактовые циклы, но я их не нашел, извините. Вы можете попробовать заглянуть внутрь QueryProcessCycleTime
и из какого источника он читает данные — может быть, вам повезло, и он читает A, B и возвращает A + B, и, возможно, вы можете посмотреть, какие источники. Я не проверял это.
Взгляни на GetProcessTimes. Это даст вам количество ядра и пользовательское время, использованное вашим процессом.