开发者

Getting WMI to read processor load faster

开发者 https://www.devze.com 2023-01-12 02:23 出处:网络
I have a C# application, where I have to get the processor load. According to the accepted answer for this question, my options are to either use performance counters from either WMI or the System.Dia

I have a C# application, where I have to get the processor load. According to the accepted answer for this question, my options are to either use performance counters from either WMI or the System.Diagnostics namespace. I have a problem with the System.Diagnostics performance counter (as documented here), so my only option is to use WMI. The following code shows how I read the processor load using 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.
        }
    }
}

My problem is, that it takes around half a second to retrieve the processor utilization, as can be seen from this typical snippet of output:

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

My guess is that at least part of the reason, that it takes so long to sample the load, is that the Get method call also updates other properties of the ManagementObject object. So my question is: How can I make the Get method call update faster? I would guess, that the solution is to somehow tell th开发者_运维问答e ManagementObject object to only update the processor load property, but I don't know how to do that.

As an aside, it is curious that the sample times of the output are so stable around half a second, but I am not sure if that can give any hints toward the solution.


It has to be slow, there's no other way. The CPU core is either running at full bore or it is turned off by a HALT instruction. From which it is woken up again by an interrupt. The effective CPU load is an average calculated over a period, typically one second. The amount of time it was running divided by the period.

If you make the period shorter then the calculated value gets less accurate. Make it too short and the number will just jump between 0 and 100.

You cannot change the sample rate in the WMI query afaik. You can get quicker (and noisier) updates by reading the performance counter directly. You'll find sample code in my answer in this thread.


Recommendation: Use the Win32_PerfRawData_PerfOS_Processor performance counter and the PERF_100NSEC_TIMER_INV algorithm instead of the formatted counters. The rounding can lead to some fairly inaccurate results.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号