The performance counters returned by Windows NT each have a type definition that determines how a performance monitor is supposed to use the counter to display data to the user.
The Counter Type words are divided into a number of fields, each of which defines a particular attribute of the counter. Each field can contain one of several values. Most values are mutually exclusive in their fields, with the exception that the values for the Calculation Modifiers field can be combined. The fields are later or'd into several basic counter types currently in use in Windows NT.
First, we'll list the Fields and their possible values and definitions in Table 12.3. To do this clearly we need a little nomenclature. We assume data is available for two points in time, Time 0 (T0) and Time 1 (T1). Time 1 comes after Time 0. (Time units depend on the counter definition as described below.)
The counter value at T0 we'll call C0, and at T1 we call the value C1. Some counters are computed using the counter and the one that follows it in the counter block, which is usually a base of some kind. Call these values B0 and B1 respectively.
DeltaT = T1 - T0.
DeltaC = C1 - C0.
DeltaB = B1 - B0.
Table 12.3 Counter Type Field Definitions
Field name | Value name | Definition |
Size | PERF_SIZE_DWORD | 4 bytes long. |
Size | PERF_SIZE_LARGE | 8 bytes long. |
Size | PERF_SIZE_ZERO | Size is in CounterLength field of COUNTER_DEFINITION structure. |
Size | PERF_SIZE_VARIABLE_LEN | Size is in first DWORD of data. |
Type | PERF_TYPE_NUMBER | A number (not a counter). |
Type | PERF_TYPE_COUNTER | An increasing numeric value. |
Type | PERF_TYPE_TEXT | A text field. |
Type | PERF_TYPE_ZERO | Display a zero always. |
SubType of Type PERF_TYPE_NUMBER |
PERF_NUMBER_HEX | Display as hexadecimal number. |
SubType of Type PERF_TYPE_NUMBER |
PERF_NUMBER_DECIMAL | Display as decimal number. |
SubType of Type PERF_TYPE_NUMBER |
PERF_NUMBER_DEC_1000 | Display as decimal number/1000. |
SubType of Type PERF_TYPE_COUNTER |
PERF_COUNTER_VALUE | Display DeltaC. |
SubType of Type PERF_TYPE_COUNTER |
PERF_COUNTER_RATE | Display DeltaC/DeltaT. |
SubType of Type PERF_TYPE_COUNTER |
PERF_COUNTER_FRACTION | Display DeltaC/DeltaB. |
SubType of Type PERF_TYPE_COUNTER |
PERF_COUNTER_BASE | Don't display, just use in calculating other counter. |
SubType of Type PERF_TYPE_COUNTER |
PERF_COUNTER_ELAPSED | Display T1 - C1, meaning subtract counter from current time. |
SubType of Type PERF_TYPE_COUNTER |
PERF_COUNTER_QUEUELEN | Space-Time product of queue length. (C1 + (T1 * B1))/DeltaT |
SubType of Type PERF_TYPE_COUNTER |
PERF_COUNTER_HISTOGRAM | Counter begins or ends a histogram. |
SubType of Type PERF_TYPE_TEXT |
PERF_TEXT_UNICODE | Text is Unicode. |
SubType of Type PERF_TYPE_TEXT |
PERF_TEXT_ASCII | ASCII using CodePage as defined by PERF_OBJECT_TYPE.CodePage. |
Timer Subtype | PERF_TIMER_TICK | Uses frequency in PERF_DATA_BLOCK.PerfFreq. |
Timer Subtype | PERF_TIMER_100NS | Time is in units of 100 nanoseconds. |
Timer Subtype | PERF_OBJECT_TIMER | Time is in units defined in PERF_OBJECT_TYPE.PerfFreq. |
Calculation Modifiers | PERF_DELTA_COUNTER | Compute difference first: DeltaC. |
Calculation Modifiers | PERF_DELTA_BASE | Compute the base difference: DeltaB. |
Calculation Modifiers | PERF_INVERSE_COUNTER | After computing, subtract resulting fraction from 1. |
Calculation Modifiers | PERF_MULTI_COUNTER | Sum of multiple instances. Divide by number of instances (in B1) after computing to get average. |
Display | PERF_DISPLAY_NO_SUFFIX | No suffix. |
Display | PERF_DISPLAY_PER_SEC | "/second" |
Display | PERF_DISPLAY_PERCENT | "%" |
Display | PERF_DISPLAY_SECONDS | "seconds" |
Display | PERF_DISPLAY_NOSHOW | Don't display the value at all. |
In the next table we define a number of pre-existing counter types used in counter definitions. These are combinations of the above flags. Currently, Performance Monitor supports only the counter types defined in Table 12.4, except for PERF_COUNTER_TEXT and PERF_COUNTER_QUEUELEN_TYPE.
Table 12.4 Predefined Counter Types and How to Display Them
Counter type name | Composition | Definition/computation | ||||||
PERF_COUNTER_COUNTER | PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC | 32-bit rate of counts. DeltaC / DeltaT The most common sort of counter. |
||||||
PERF_COUNTER_TIMER | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT | 64-bit Timer. (DeltaC / DeltaT) * 100 The most common sort of timer. |
||||||
PERF_COUNTER_QUEUELEN_TYPE | PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX | Space-Time product of queue
length. (C1 + (T1 * B1))/DeltaT Not used in the current release of Windows NT. |
||||||
PERF_COUNTER_BULK_COUNT | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC | 64-bit rate of count. Used
to count byte transmission rates. DeltaC / DeltaT |
||||||
PERF_COUNTER_TEXT | PERF_SIZE_VARIABLE_LEN | PERF_TYPE_TEXT | PERF_TEXT_UNICODE | PERF_DISPLAY_NO_SUFFIX | Indicates the counter is not
a counter but rather Unicode text. Display as text. |
||||||
PERF_COUNTER_RAWCOUNT | PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX | A raw count that should not
be averaged. Used for instantaneous counts. Display B1. |
||||||
PERF_SAMPLE_FRACTION | PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DELTA_COUNTER | PERF_DELTA_BASE | PERF_DISPLAY_PERCENT | A count that is either 1 or
0 on each sampling interrupt. Display as percentage. (DeltaC / DeltaB) * 100 |
||||||
PERF_SAMPLE_COUNTER | PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX | A count that is sampled on each
sampling interrupt. Display without a suffix. DeltaC/DeltaB |
||||||
PERF_COUNTER_NODATA | PERF_SIZE_ZERO | PERF_DISPLAY_NOSHOW | This is not to be displayed. | ||||||
PERF_COUNTER_TIMER_INV | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT | This is used to show how busy the processor is, but it is really time in the idle process. | ||||||
PERF_SAMPLE_BASE | PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW | The divisor for a sample (previous
counter). Check that this is > 0 before dividing! Don't display. |
||||||
PERF_AVERAGE_TIMER | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_SECONDS | A timer which, when divided by a base, yields a time per operation. | ||||||
PERF_AVERAGE_BASE | PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW | Used as the denominator in the
computation of time or count averages. Do not display. |
||||||
PERF_AVERAGE_BULK | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_NO_SUFFIX | A 64-bit count which when divided
(typically) by the number of operations gives (typically)
the bytes/operation. DeltaC / DeltaB |
||||||
PERF_100NSEC_TIMER | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT | 64-bit timer in 100 nanosecond
units. (DeltaC / DeltaT) * 100 |
||||||
PERF_100NSEC_TIMER_INV | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT | 64-bit timer inverse, that
is, we measure idle time, then display (1-(idle time)) (1 - (DeltaC / DeltaT)) * 100 |
||||||
PERF_COUNTER_MULTI_TIMER | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_TIMER_TICK | PERF_MULTI_COUNTER | PERF_DISPLAY_PERCENT | Timer for multiple instances,
so sum of result can exceed 100%. Number of instances is
in the next counter. 100 * (DeltaC / DeltaT) / B1 Display as percentage. |
||||||
PERF_COUNTER_MULTI_TIMER_INV | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_MULTI_COUNTER | PERF_TIMER_TICK | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT | Display inverse of timer for multiple
instances. 100 * (1 - ((DeltaC / DeltaT) / B1)) |
||||||
PERF_COUNTER_MULTI_BASE | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_MULTI_COUNTER | PERF_DISPLAY_NOSHOW | Base for _MULTI_ counters. Do not display. |
||||||
PERF_100NSEC_MULTI_TIMER | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_DELTA_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_MULTI_COUNTER | PERF_DISPLAY_PERCENT | Timer for multiple instances,
so sum of result can exceed 100%. Number of instances is
in the next counter. 100 * (DeltaC / DeltaT) / B1 Display as percentage. |
||||||
PERF_100NSEC_MULTI_TIMER_INV | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_DELTA_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_MULTI_COUNTER | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT | Display inverse of timer for multiple
instances. 100 * (1 - ((DeltaC / DeltaT) / B1)) |
||||||
PERF_RAW_FRACTION | PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_PERCENT | Fraction of next counter, display
as a percentage. (C/B) * 100 |
||||||
PERF_RAW_BASE | PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW | Used as a base for the preceding
counter. Do not display. |
||||||
PERF_ELAPSED_TIME | PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_ELAPSED | PERF_OBJECT_TIMER | PERF_DISPLAY_SECONDS | The data collected in this counter is actually the start time of the item being measured. For display, this data is subtracted from the snapshot time to yield the elapsed time (the difference between the two). In the definition to the left, the PerfTime field of the PERF_OBJECT_TYPE contains the sample time as indicated by the PERF_OBJECT_TIMER bit and the difference is scaled by the PerfFreq of the PERF_OBJECT_TYPE to convert the time units into seconds. |
Whew! Okay, now you know how to compute and display all the different types of counters that come back from the call to the Configuration Registry when you specify HKEY_PERFORMANCE_DATA as the key. Hey, we said you'd be stimulating at parties, didn't we? Now get to work on that monitor!