System.Diagnostics.PerformanceCounter and % Processor Time on multi-core or multi-cpu
While trying to build a task-manager type tool, I noticed that the idle task on my machine sometime consumed over 100% of the CPU! 160%, even 180%. What's going on? I asked the base-class framework team and they've clued me in:
Process and Processor have different aggregation types.
· “\Process(…)\% Processor Time” can go up to N*100 (where N is the number of CPUs) because it adds up the CPU usage of the requested process across all the CPUs.
· “\Process(_Total)\% Processor Time” should always be around N*100 (where N is the number CPUs) because it adds up the CPU usage of each process, including the idle process.
· “\Processor(…)\% Processor Time” can go up to 100 because it’s the CPU usage of the requested CPU.
· “\Processor(_Total)\% Processor Time” can go up to 100 because it’s the average CPU usage across all CPUs.
In the above, Process(...) indicates a particular instance of the perf counter, pertaining to a particular process on the machine. If you have a dual-core machine or a multi-cpu machine - these days even basic laptops have Core Duos - then you will see this behavior.
Note: this assumes your code uses NextValue(), not NextSample. Something like this:
1 public class MyProcessInfo : INotifyPropertyChanged, IDisposable
2 {
3 System.Diagnostics.Process _p;
4 System.Diagnostics.PerformanceCounter _perfCounter;
5 public MyProcessInfo(System.Diagnostics.Process p)
6 {
7 _p = p;
8 _Id = p.Id;
9 _WorkingSetInKbytes = p.WorkingSet64 / 1024;
10 _perfCounter =
11 new System.Diagnostics.PerformanceCounter("Process",
12 "% Processor Time",
13 p.ProcessName,
14 true);
15 _perfCounter.NextValue();
16 }
17
18 public void UpdateUtilization()
19 {
20 CpuUtilization = (int)(_perfCounter.NextValue());
21 }
Keep in mind that you need to delay "about 1 second" between calls to NextValue(), as per the documentation!
Comments
- Anonymous
November 13, 2008
I think you made a type error, the correct should be: · “Processor(…)% Processor Time” can NOT go up to 100 because it’s the CPU usage of the requested CPU. · “Processor(_Total)% Processor Time” can NOT go up to 100 because it’s the average CPU usage across all CPUs.