1
votes

I came across a different behavior in the calculation of CPU itilization. In my code i use performance counter "Processor Time", instance "_Total" and it seems to work okay (Windows Performance monitor show the same value, Sysinternals Process Explorer as well) , but built-in Task Manager in Windows 8 or 10 shows much less, if power options allows balance CPU speed and CPU is at a given moment running at a lower frequency.

Is there any C# of C function, perf. counter .. to provide this (Task Manager) value, or read the current CPU frequency and somehow calculate it?

1
Using _Total, and thus get the processor time used for all processes instead of just yours, is pretty unusual and not what Task Manager displays in its Processes tab. The category matters, there is "Processor" and "Processor Information". Task Manager uses the latter, it is a more recent counter category that tries to compensate for variable clock rates and hyper-threading. The best way is certainly to not add a doodah to your program that is trivially visible without any help.Hans Passant
thanks, however category "Processor" and "Processor Information" gives me the same numbers, even CPU is running at about half frequency.Viliam

1 Answers

3
votes

If someone will face this requirement, I want to show you how I finally solved it:

Apparently the Windows 8 includes a performance monitor counter named "% Processor Utility". And this is the one, that is shown in the Task Manager of Win 8, and Win 10 as CPU Utilization. This counter unlike "% Processor Time", which is usually used to display the CPU usage, takes into account the balanced CPU speed.

% Processor Utility is the amount of work a processor is completing, as a percentage of the amount of work the processor could complete if it were running at its nominal performance and never idle. On some processors, Processor Utility may exceed 100%.

In c # code snippet:

PerformanceCounter _cpuCounter = new PerformanceCounter("Processor Information", "% Processor Utility", "_Total");
CounterSample firstValue = _cpuCounter.NextSample();
Thread.Sleep(500);
CounterSample secondValue = _cpuCounter.NextSample();
    string cpuUsage = CounterSample.Calculate(firstValue, secondValue).ToString("0.0");