Performance Counter Definitions

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!