2015-11-09

Windows PerfCounters and Powershell - Raw vs. Formatted values


How to interpret Raw data from Windows performance counters.


Tip: An alias for Get-CimInstance is GCim and alias for Get-WmiObject is GWmi.

In the first blog post, I covered what WMI/CIM is and how to get info from there. Last I talked about was RawData counters:
Get-CimInstance -Class Win32_PerfRawData_PerfOS_Processor

Name : _Total
...
PercentIdleTime : 78061457390



Understanding RawData:

By itself, a RawData value is a sample but important thing is to determine what concrete sample value actually is and how to convert it to a form we understand. In this example, MSDN tells us PercentIdleTime is a counter of type 542180608:
  PercentIdleTime
        Data type: uint64
        Access type: Read-only
        Qualifiers: DisplayName ("% Idle Time") , CounterType (542180608) , DefaultScale (0) , PerfDetail (400)

Bear in mind, most of RawData counters need 2 samples to produce humanly readable result thus now we need a formula to convert Raw counter values into something meaningful.
Numeric-to-Name conversion (542180608 -> PERF_100NSEC_TIMER) of counter type values is listed in this MSDN page. The actual formula is then located under entries listed here as described in this page:

(N1 - N0) / (D1 - D0) x 100, where the denominator (D) represents the total elapsed time of the sample interval, and the numerator (N) represents the portions of the sample interval during which the monitored components were active.

This translates to:
      $Val =
      (
      (PercentIdleTime_Sample[n] - PercentIdleTime_Sample[n-1])
      /
      (Timestamp_Sys100NSSample[n] - Timestamp_Sys100NSSample[n-1])
      ) *100
Note: Although formula is correct according to documentation, it usually summarizes result over all CPU's (say, when fetching CPU utilization per process/thread) thus the result will most likely be well over 100% on modern boxes. In such case, we need to divide samples with total number of CPU's:
      $Val =
      (
      (PercentIdleTime_Sample[n] - PercentIdleTime_Sample[n-1])
      /(
      (Timestamp_Sys100NSSample[n] - Timestamp_Sys100NSSample[n-1])
      *$TotProc)
      ) *100


With the Class Win32_PerfRawData_PerfOS_Processor it's easy. It has Instance named _Total and when you apply formula to its values you will get proper result. I will talk of this more in next blogs.

Conclusion:

So, why Formatted and Raw counters? After all, Formatted data is coming from Raw counters. First, we have to remember that Raw counters are used for collecting N samples as the naked number obtained is meaningless. So, let's say that in above example I asked for CPU usage by certain process that I only just started. Formatted counter will either have 0 or NaN value in it while Raw counter will produce some number given that sampling time is usually 100ns. Well, you might say, it's the same as "get formatted sample | check if it is a number | no? -> take another formatted sample" and you'd be right. But you should take into account the rounding happening in calculating Formatted values internally as well as in your script (check that data type of Formatted counters is usually UINT!) and also the latency involved in WMI provider populating formatted data counters.

If you are set on using Raw counters, bear in mind you need formulas for transforming Samples into Values.

All said, it is actually a question of choice whether to use one type or the other as you will see in the script I'll be describing in the final blog.

Examples of calculating Value from Counter type and samples @Sysinternals and @MSDN.

Next blog will deal with various ways to obtain performance data.

In this series:
BLOG 1: PerfCounters infrastructure
BLOG 2: PerfCounters Raw vs. Formatted values
BLOG 3: PerfCounters, fetching the values
BLOG 4: PerfCounters, CPU perf data
BLOG 5: PerfCounters, Memory perf data
BLOG 6: PerfCounters, Disk/IO perf data
BLOG 7: PerfCounters, Network and Contention perf data

No comments:

Post a Comment