Programmatically Tracking CPU Utilization


Issue/Challenge

Microsoft Windows* does not provide a simple mechanism for programmatically calculating the percentage of CPU utilization. The primary API provided, Performance Data Helper (PDH), is not highly intuitive and does not provide for easy integration into applications or simple utilities.


Solution

The CPUUsage class provides an interface to easily calculate the maximum, minimum, and average CPU utilization over a period of time for a given sample rate by wrapping the PDH functionality. The CPUUsageUtil command-line utility provides one example of a simple utility that can be created to monitor CPU utilization percentage using the CPUUsage class.


The CPUUsage Class

The CPUUsage class provides the following public interface:

The single argument to the constructor is used to specify the minimum amount of time that must pass before another sample can be acquired. The lower this is set, the more data is acquired, but at the expense of higher program overhead. The default minimum sample difference is one second. The GetUsage() method is used to tell the CPUUsage object to acquire a new sample. The Boolean pointer that is passed to GetUsage() is updated to indicate whether or not a sample was actually acquired. Remember, if the minimum sample rate passed to the constructor has not yet passed, then no sample is acquired. The GetAverageUsage(), GetMaxUsage(), and GetMinUsage() functions are used to obtain respectively the average, maximum, and minimum percentage CPU utilization recorded for a particular sample over the life of this CPUUsage object.

CPUUsageUtil

CPUUsageUtil provides one simple example of how the CPUUsage class can be put to use. The utility is a command-line application consisting of two threads. One thread monitors the CPU utilization percentage at an interval specified on the command line, or every 500ms by default, and the second thread just sits there waiting for a carriage return so that it can kill the first thread. Here is the code involving the CPUUsage object:

   CPUUsage x(sampleMillis);

   ...

while(loop){

int u =

x.GetUsage(&fNewSample);

//u =

x.GetUsage();

printf("%d

(%s)
", u, fNewSample ? "True" : "False);

Sleep(sampleMillis);

 }

 ...

//polling done, print out

results

printf("Average CPU Usage:

%d
", x.GetAverageUsage());

printf("Maximum CPU Usage:

%d
", x.GetMaxUsage());

printf("Minimum CPU Usage:

%d
", x.GetMinUsage());   

...

 

The object is ins tantiated with the given minimum sample rate. In the main loop, a sample is recorded, and the program sleeps for the given sample rate. Once a carriage return is recorded in the second thread, the "loop" variable is set to false and the utility discontinues sampling. The final results recorded by the CPUUsage object print out before the utility exits.


Use Scenarios

Application code that performs at or near 100% CPU utilization is a prime target for optimization. Therefore, identifying frequently executed segments of your code that also achieve maximum CPU utilization should be a preliminary step before performing any optimization. Furthermore, monitoring the percentage of CPU utilization has numerous applications beyond performance optimization.

Built in Windows CPU utilization tools - perfmon and task manager - are inadequate. While you can analyze the percentage of CPU utilization with them you must do so manually. Neither utility provides built-in features for automated analysis of CPU utilization; nor do they allow you to isolate analysis to a subset of the application under test. Additionally, the Win32 API for monitoring system performance counters, PDH, is not highly intuitive. This is where the CPUUsage class comes in handy.

The CPUUsage class can be used to create any number of useful utilities to monitor specific instances of CPU utilization. One such utility, CPUUsageUtil, is provided. CPUUsageUtil analyzes the percentage of CPU utilization until it receives a carriage return from standard input. This allows for easily scripting the starting and stopping points for CPU utilization analysis. For instance a developer may have an automated build and test process in which a portion of the test includes CPU utilization evaluation. Using CPUUsageUtil, the developer can script the analysis to automatically begin and end on demand, capturing only the relevant data. With additional scripting or modification to the utility, CPU utilization analysis could be required to occur for a specified duration of time, at certain times of day, or limited to any other set of user-defined conditions.

Conversely the utility could be modified to function as an alarm, triggering events when a specified CPU utilization threshold is broken. The alarm could be set to go off when the system is overburdened or upon the completion of a task for high and low CPU utilization respectively.

As a high-level indicator, the CPUUsageUtil can be used to get a broad, program-level perspective of whether or not the CPU is even reaching 100%. At a lower level, the CPUUsage class can be directly embedded into source code to poll at specific areas that may be suspected hotspots. If an application is not achieving 100% CPU utilization, then it is most likely IO bound, and optimization time should be spent targeting memory, disk, and/or network access rather than instruction-level optimization.

When using the CPUUsage class within application source code, the application can trigger monitoring at a set interval:

  • Using a timer
  • At set locations in the code with callbacks
  • By calling into the CPUUsage object directly

 

If a developer wants to analyze the average, maximum, or minimum CPU utilization for a particular region of his/h er application, simply create a CPUUsage object and send polling requests at desired intervals. In this fashion, multiple CPUUsage objects can be created to monitor CPU utilization at various regions of code.

If you do get to the point where you determine instruction-level optimizations would benefit an application, then you'll need a higher-precision tool than the code provided. When it comes to isolating individual instructions or basic blocks that are consuming CPU cycles, the Intel® VTune™ Performance Analyzer is hands-down the best tool that I have used.


Conclusion

CPU utilization is a key metric for optimization, performance analysis, and workload evaluation. However, the built-in Windows facilities for tracking CPU Utilization provide limited flexibility. The CPUUsage class provided attempts to alleviate this issue by providing a simple interface that can be used to programmatically track CPU percentage. The level of control provided by the CPUUsage class allows virtually unlimited CPU utilization monitoring options for the application developer.


Additional Resources

 


CPU Usage Code Sample (ZIP file, 3,643 bytes)

 

Étiquettes:
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.