Like this? Please check out my latest book, Writing High-Performance .NET Code.
Updated 2/4/2009: I changed the implementation of these classes from the original:
- Instead of a critical section, InterlockedIncrement/Decrement is used.
- The sample driver program now demos using multiple threads using the CpuUsage class to show thread safety.
Download the C++ and C# projects that accompany this article.
Just to make it clear, there is no API called GetProcessCpuPercentage(). To find out the percentage, we can use some other, real APIs and do some calculations. Before getting to the equation and code, let’s discuss the different types of time available.
There are four types of time:
- Wall time – The actual, real-world progression of time as measured by you on your watch.
- Kernel time – The amount of time spent in kernel mode (protected, high-order mode of operation)
- User time – the amount of time spent in user-mode (often by the process itself)
- Idle time – nothing going on at all
Kernel, User, and Idle sum to total time, which is approximately wall-time.
Each process spends some time in kernel mode and some time in user mode. We just need to compare the time spent by a process to the time spent by all processes on the computer, since the last time we made such a measurement. It is important to note that we do NOT take into account the idle time.
Thus, the equation is
There are two APIs that are useful:
- GetProcessTimes – Get times for a specific process
- GetSystemTimes – Get total times for the entire system (all CPUs)
The times reported are absolute, so what we are actually interested is in the difference between the current times and those from a previous run.
Armed with this information, we can calculate the CPU usage for the current process (or any arbitrary process, for that matter).
Let’s do it first in C++ to demonstrate usage of the APIs.
CPU Usage Percentage in C++
Here’s the header file:
The GetUsage() method is where the work occurs. The other methods are to help in the calculations. The critical section run count enables the code to be called in a multi-threaded environment without problems. I also prevent the code from being called more often than every 250ms. Here is the complete implementation:
In order to test this, here is a simple program that starts two threads that run an infinite loop, eating the processor. On a dual-core system, this process will take roughly 85-95% of the CPU. I also start two threads to access the usage object and poll the CPU usage in order to demonstrate the thread safety of the object.
In C#, The System.Diagnostics.Process can give us the time information for a specific process. However, we still need the Win32 API call for getting the total system times (GetSystemTimes). The Process class reports times in TimeSpans, not FILETIME, so our class is modified accordingly.
These classes can now be used wherever you need to monitor the CPU usage of a process.
Notice any improvements to be made? Leave a comment.
Download C++ and C# projects
Check out my latest book, the essential, in-depth guide to performance for all .NET developers:
Writing High-Performance.NET Code by Ben Watson. Available now in print and as an eBook at: