Получение WMI для чтения загрузки процессора быстрее - PullRequest
2 голосов
/ 19 августа 2010

У меня есть приложение C #, где я должен получить загрузку процессора. В соответствии с принятым ответом на этот вопрос я могу использовать счетчики производительности либо из WMI, либо из пространства имен System.Diagnostics. У меня проблема со счетчиком производительности System.Diagnostics (как указано здесь ), поэтому мой единственный вариант - использовать WMI. Следующий код показывает, как я читаю загрузку процессора с помощью WMI:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;

namespace ProcessorUtilizationSpike
{
    class Program
    {
        private static ManagementObject processor;

        static void Main(string[] args)
        {
            processor = new ManagementObject("Win32_PerfFormattedData_PerfOS_Processor.Name='_Total'");

            while(true)
            {
                PrintTimedMeasure();
            }
        }

        static void PrintTimedMeasure()
        {
            DateTime start = DateTime.Now;
            UInt64 wmi = WMIMeasure();
            DateTime stop = DateTime.Now;
            Console.WriteLine("wmi : " + wmi + ", time: " + (stop - start));
        }

        static UInt64 WMIMeasure()
        {
            processor.Get();
            return ((UInt64)processor.Properties["PercentProcessorTime"].Value); // this property corresponds to a UInt64, see the Type property.
        }
    }
}

Моя проблема в том, что для извлечения загрузки процессора требуется около полсекунды, как видно из этого типичного фрагмента вывода:

wmi : 6, time: 00:00:00.5156250
wmi : 3, time: 00:00:00.5156250
wmi : 4, time: 00:00:00.5000000
wmi : 3, time: 00:00:00.5156250
wmi : 3, time: 00:00:00.5000000

Я предполагаю, что, по крайней мере, одна из причин того, что выборка нагрузки занимает так много времени, заключается в том, что вызов метода Get также обновляет другие свойства объекта ManagementObject. Итак, мой вопрос: как я могу ускорить обновление вызова метода Get? Я предполагаю, что решение состоит в том, чтобы как-то сказать объекту ManagementObject обновить только свойство загрузки процессора, но я не знаю, как это сделать.

Кроме того, любопытно, что время выборки выходного сигнала настолько стабильно около полсекунды, но я не уверен, может ли это дать какие-либо подсказки для решения.

Ответы [ 2 ]

3 голосов
/ 19 августа 2010

Это должно быть медленно, другого пути нет.Ядро ЦП либо работает на полнопроходной линии, либо оно отключено инструкцией HALT.От которого он снова просыпается от прерывания.Эффективная загрузка ЦП - это среднее значение, рассчитанное за период, обычно за одну секунду.Время, в течение которого он работал, делится на период.

Если вы сделаете период короче, то вычисленное значение станет менее точным.Сделайте его слишком коротким, и число будет просто прыгать между 0 и 100.

Вы не можете изменить частоту дискретизации в запросе WMI.Вы можете получать более быстрые (и более шумные) обновления, непосредственно читая счетчик производительности.Пример кода в моем ответе вы найдете в этой теме .

2 голосов
/ 10 декабря 2011

Рекомендация: используйте счетчик производительности Win32_PerfRawData_PerfOS_Processor и алгоритм PERF_100NSEC_TIMER_INV вместо отформатированных счетчиков. Округление может привести к довольно неточным результатам.

...