Pregunta

I've looked at WMI, negative CPU usage value and Timestamp_Sys100NS in past but I am not doing anything with boot time only delta time between two readings.

When CPU usage is very low i.e. System Idle Process shows as 99% I get Negative CPU usage readings.

I've adapted the code and formula from an MSDN article but can't tell why it might be wrong.

http://msdn.microsoft.com/en-us/library/aa392397%28VS.85%29.aspx

The commented out line at the bottom was only giving me results of 0 or 100, I assume this was because of Integer rounding or something similar so I broke it out into separate parts as doubles before dividing.

        ulong N1 = 0;
        ulong D1 = 0;
        ulong N2 = 0;
        ulong D2 = 0;

        ManagementScope scope = new ManagementScope("\\\\" + Machine + "\\root\\cimv2");
        scope.Connect();

        WqlObjectQuery wqlQuery = new WqlObjectQuery("SELECT PercentProcessorTime, TimeStamp_Sys100NS FROM Win32_PerfRawData_PerfOS_Processor Where Name = '_Total'");
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, wqlQuery);

        foreach (ManagementObject proc in searcher.Get())
        {
            N1 = ulong.Parse(proc.Properties["PercentProcessorTime"].Value.ToString());
            D1 = ulong.Parse(proc.Properties["TimeStamp_Sys100NS"].Value.ToString());
        }

        System.Threading.Thread.Sleep(500);

        foreach (ManagementObject proc in searcher.Get())
        {
            N2 = ulong.Parse(proc.Properties["PercentProcessorTime"].Value.ToString());
            D2 = ulong.Parse(proc.Properties["TimeStamp_Sys100NS"].Value.ToString());
        }


        double cpu = N2 - N1;
        double time = D2 - D1;
        var x = (1 - (cpu / time)) * 100;
        //var x = (1 - ((N2 - N1) / (D2 - D1))) * 100;
        context.Response.Write(x);
¿Fue útil?

Solución

I had the exact same problem, I am working with Perl in the example but the logic as you can see below is the same, I used the formula described on that Microsoft document.

$average = (1 - ( ($n2-$n1) / ($d2-$d1) ) ) * 100;

I tried to solve this for days but in the end I just went for the most obvious solution:

if ($average <0) { $average = 0; }

In the end if the CPU is very low no one really cares. In my case I was looking for load spikes and long-range loads. Maybe you are interested in small changes I don't know, to me 1% or 0% is exactly the same.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top