PROCESSOR_POWER_STATE

Starting with Windows 2000, a PROCESSOR_POWER_STATE structure (formally _PROCESSOR_POWER_STATE) is nested within the KPRCB for each logical processor. It is thought to have no self-standing existence.

The PROCESSOR_POWER_STATE is a highly variable implementation detail for the kernel. It might ordinarily be worth attention only as an aid to debugging very particular sorts of problems, except for the very curious point that Microsoft seems to have regarded it initially as not internal.

Documentation Status

A C-language definition appeared in NTPOAPI.H from the Device Driver Kit (DDK) for Windows XP, albeit in a directory of headers that are specific to targeting Windows 2000 (and in another for Windows Me, which is a different operating system of no concern here). What’s noteworthy is not just that this definition for Windows 2000 is the only definition that Microsoft has ever disclosed but also that Microsoft keeps disclosing it. Even as late as the Windows Driver Kit (WDK) for Windows 10, which to a large extent forces programmers to target nothing older than Windows 7, NTPOAPI.H has the C-language definition of PROCESSOR_POWER_STATE for Windows 2000. It’s in a conditional compilation block with a comment “win2k only”, but why does it remain? Why, even, did Microsoft ever publish it?

Though Microsoft is not known to have published a C-language definition of the PROCESSOR_POWER_STATE for any other version, the practical equivalent for all versions starting with Windows 2000 SP3 is readily available as type information in public symbol files for the kernel.

Variability

Whatever wider use may have been intended for the PROCESSOR_POWER_STATE in Windows 2000, or even while preparing the DDK for Windows XP, the structure was evidently soon regarded as internal in the sense that nothing of its layout need be preserved from one build to another. Indeed, it was all but completely redesigned as soon as Windows Vista, and nearly as much again for Windows 7.

In the following table which summarises the variability just from its changing size, different builds of the same version are distinguished as early and late because they are known to vary the structure even if they don’t change the size. These descriptions, as early and late, are then used throughout the article as a shorthand. Even this does not suffice for versions 5.1 and 5.2, whose last service packs (SP3 and SP2, respectively) brought their own small variations.

Version Size (x86) Size (x64)
5.0 0x88  
early 5.1 (before SP2);
late 5.1 ;
early 5.2 (before SP1);
late 5.2
0x0120 0x0170
early 6.0 (before SP1) 0xE0 0x0138
late 6.0 0xC8 0x0118
6.1 0xC8 0x0100
6.2 0x0180 0x01C8
6.3 0x0190 0x01E0
10.0 to 1607 0x0180 0x01D0
1703 0x0180 0x01D8
1709 to 2004 0x01A8 0x0200

Layout

The changes in size do not even hint at the scale of reorganisation within. The PROCESSOR_POWER_STATE is here taken as three different structures. Through all the tables that follow, names, types and offsets are from public symbol files.

Original (Before Windows Vista)

For some sense of how much the structure (and thus processor power management as a feature) was reworked for Windows Vista, look for how few of the members that are defined for version 5.0 are still in the structure for version 6.0.

Offset (x86) Offset (x64) Definition Versions Remarks
0x00 0x00
VOID 
(FASTCALL *IdleFunction) (
    PROCESSOR_POWER_STATE *);
5.0 to 5.2 next at 0x00
0x04 0x08
ULONG Idle0KernelTimeLimit;
5.0 to 5.2  
0x08 0x0C
ULONG Idle0LastTime;
5.0 to 5.2  
0x0C 0x10
PVOID IdleHandlers;
5.1 to 5.2  
0x0C (5.0);
0x10
0x18
PVOID IdleState;
5.0 to 5.2  
0x14 0x20
ULONG IdleHandlersCount;
5.1 to 5.2  
0x10 (5.0);
0x18
0x28
ULONGLONG LastCheck;
5.0 to 5.2  
0x18 (5.0);
0x20
0x30
PROCESSOR_IDLE_TIMES IdleTimes;
5.0 to 5.2 next at 0x18 and 0x20
0x38 (5.0);
0x40
0x50
ULONG IdleTime1;
5.0 to 5.2  
0x3C (5.0);
0x44
0x54
ULONG PromotionCheck;
5.0 to 5.2  
0x40 (5.0);
0x48
0x58
ULONG IdleTime2;
5.0 to 5.2  
0x44 (5.0);
0x4C
0x5C
UCHAR CurrentThrottle;
5.0 to 5.2  
0x45 (5.0);
0x4D
 
UCHAR ThrottleLimit;
5.0 only  
0x5D
UCHAR ThermalThrottleLimit;
5.1 to 5.2  
0x46 (5.0);
0x4E
 
UCHAR Spare1 [2];
5.0 only  
0x5E
UCHAR CurrentThrottleIndex;
5.1 to 5.2  
0x4F 0x5F
UCHAR ThermalThrottleIndex;
5.1 to 5.2  
0x48 (5.0);
0x50
 
ULONG SetMember;
5.0 only  
 
ULONG PerfSystemTime;
early 5.1;
early 5.2
 
0x60
ULONG LastKernelUserTime;
late 5.1;
late 5.2
next at 0x40 and 0x50
0x54  
PVOID AbortThrottle;
5.0 only  
0x64
ULONG PerfIdleTime;
5.1 before SP3;
5.2 before SP2
 
ULONG LastIdleThreadKernelTime;
5.1 SP3;
5.2 SP2
 
0x50 (5.0);
0x58
0x68
ULONGLONG DebugDelta;
5.0;
5.1 before SP3;
5.2 before SP2
 
ULONG PackageIdleStartTime;
5.1 SP3;
5.2 SP2
 
0x5C 0x6C
ULONG PackageIdleTime;
5.1 SP3;
5.2 SP2
 
0x58 (5.0);
0x60
0x70
ULONG DebugCount;
5.0 to 5.2  
0x5C (5.0);
0x64
0x74
ULONG LastSysTime;
5.0 to 5.2 next at 0xA8 and 0xF0

The IdleFunction is called whenever the kernel is in its idle loop but the processor has no NextThread to run. NTPOAPI.H defines PROCESSOR_IDLE_FUNCTION for such a function’s prototype.

Though IdleHandlers is defined as a pointer to void, what it points to is an array of POP_IDLE_HANDLER structures. These are built from information that can be supplied from outside the kernel through the ZwPowerInformation function when given ProcessorStateHandler or ProcessorStateHandler2 (starting in version 5.1) as its information level. Both these information levels are failed trivially in version 6.0 and higher.

The LastSysTime is the only original member that survives even to Windows 7.

Version 5.0 ends the structure with 0x28 spare bytes, presumably to allow for expansion. This turns out to have been far too small. it got used for two arrays, beyond which the structures gets many new members.

Offset (x86) Offset (x64) Definition Versions
0x60 (5.0);
0x68
 
ULONG Spare2 [10];
5.0 only
0x78
ULONGLONG TotalIdleStateTime [3];
5.1 to 5.2
0x80 0x90
ULONG TotalIdleTransitions [3];
5.1 to 5.2

Appended for Windows XP

Offset (x86) Offset (x64) Definition Versions Remarks
0x90 0xA0
ULONGLONG PreviousC3StateTime;
5.1 to 5.2  
0x98 0xA8
UCHAR KneeThrottleIndex;
5.1 to 5.2  
0x99 0xA9
UCHAR ThrottleLimitIndex;
5.1 to 5.2  
0x9A 0xAA
UCHAR PerfStatesCount;
5.1 to 5.2  
0x9B 0xAB
UCHAR ProcessorMinThrottle;
5.1 to 5.2  
0x9C 0xAC
UCHAR ProcessorMaxThrottle;
5.1 to 5.2  
0x9D 0xAD
UCHAR LastBusyPercentage;
5.1 before SP3;
5.2 before SP2
 
UCHAR EnableIdleAccounting;
5.1 SP3;
5.2 SP2
 
0x9E 0xAE
UCHAR LastC3Percentage;
5.1 to 5.2  
0x9F 0xAF
UCHAR LastAdjustedBusyPercentage;
5.1 to 5.2  
0xA0 0xB0
ULONG PromotionCount;
5.1 to 5.2  
0xA4 0xB4
ULONG DemotionCount;
5.1 to 5.2  
0xA8 0xB8
ULONG ErrorCount;
5.1 to 5.2  
0xAC 0xBC
ULONG RetryCount;
5.1 to 5.2  
0xB0 0xC0
ULONG Flags;
5.1 to 5.2  
0xB8 0xC8
LARGE_INTEGER PerfCounterFrequency;
5.1 to 5.2  
0xC0 0xD0
ULONG PerfTickCount;
5.1 to 5.2  
0xC8 0xD8
KTIMER PerfTimer;
5.1 to 5.2 next at 0x60 and 0x70
0xF0 0x0118
KDPC PerfDpc;
5.1 to 5.2 next at 0x88 and 0xB0
0x0110 0x0158
PROCESSOR_PERF_STATE *PerfStates;
5.1 to 5.2 next (with type change) at 0x3C and 0x48
0x0114 0x0160
NTSTATUS 
(FASTCALL *PerfSetThrottle) (
    UCHAR);
5.1 to 5.2  
0x0118 0x0168
ULONG LastC3KernelUserTime;
late 5.1;
late 5.2
 
0x0118 (early 5.1, early 5.2);
0x011C (5.1 SP2, 5.2 SP1)
 
ULONG Spare1 [2];
early 5.1;
early 5.2
 
0x016C
ULONG Spare1 [1];
5.1 SP2;
5.2 SP1 l
 
0x011C 0x016C
ULONG LastPackageIdleTime;
5.1 SP3;
5.2 SP2
 

Windows Vista

Offset (x86) Offset (x64) Definition Versions Remarks
0x00 (early 6.0) 0x00 (early 6.0)
VOID 
(FASTCALL *IdleFunction) (
    PROCESSOR_POWER_STATE *);
early 6.0 previously at 0x00
0x04 (early (6.0);
0x00
0x08 (early 6.0);
0x00
PPM_IDLE_STATES *IdleStates;
6.0 next at 0x00
0x08 0x10 (early 6.0);
0x08
ULONGLONG LastTimeCheck;
6.0  
0x10 0x18 (early 6.0);
0x10
ULONGLONG LastIdleTime;
early 6.0  
ULONGLONG IdleTimeAccumulated;
late 6.0  
0x18 0x20 (early 6.0);
0x18
PROCESSOR_IDLE_TIMES IdleTimes;
early 6.0 previously at 0x20 and 0x30
union {
    struct {
        ULONGLONG IdleTransitionTime;
    } Native;
    struct {
        ULONGLONG LastIdleCheck;
    } Hv;
};
late 6.0  
0x38 (early 6.0);
0x20
0x40 (early 6.0);
0x20
PPM_IDLE_ACCOUNTING *IdleAccounting;
6.0 next (with type change) at 0x04 and 0x08
0x3C (early 6.0);
0x24
0x48 (early 6.0);
0x28
PPM_PERF_STATES *PerfStates;
6.0 previously (with type change) at 0x0110 and 0x0158
0x40 (early 6.0);
0x28
0x50 (early 6.0);
0x30
ULONG LastKernelUserTime;
6.0 previously at 0x50 and 0x60
0x44 (early 6.0);
0x2C
0x54 (early 6.0);
0x34
ULONG LastIdleThreadKTime;
6.0  
0x48 (early 6.0);
0x30
0x58 (early 6.0);
0x38
ULONGLONG LastGlobalTimeHv;
6.0  
0x50 (early 6.0);
0x38
0x60 (early 6.0);
0x40
ULONGLONG LastProcessorTimeHv;
6.0  
0x58 (early 6.0);
0x40
0x68 (early 6.0);
0x48
UCHAR ThermalConstraint;
6.0 next at 0x2C and 0x30
0x59 (early 6.0);
0x41
0x69 (early 6.0);
0x49
UCHAR LastBusyPercentage;
6.0  
0x5A (early 6.0);
0x42
0x6A (early 6.0);
0x4A
union {
    USHORT AsUSHORT;
    struct {
        USHORT PStateDomain : 1;                // 0x0001
        USHORT PStateDomainIdleAccounting : 1;  // 0x0002
        USHORT Reserved : 14;
    };
} Flags;
6.0  
0x60 (early 6.0);
0x48
0x70 (early 6.0);
0x50
KTIMER PerfTimer;
6.0 previously at 0xC8 and 0xD8
0x88 (early 6.0);
0x70
0xB0 (early 6.0);
0x90
KDPC PerfDpc;
6.0 previously at 0xF0 and 0x0118
0xA8 (early 6.0);
0x90
0xF0 (early 6.0);
0xD0
ULONG LastSysTime;
6.0 previously at 0x64 and 0x74;
next at 0x30 and 0x34
0xAC (early 6.0);
0x94
0xF8 (early 6.0);
0xD8
KPRCB *PStateMaster;
6.0  
0xB0 (early 6.0);
0x98
0x0100 (early 6.0);
0xE0
ULONG_PTR PStateSet;
6.0  
0xB4 (early 6.0);
0x9C
0x0108 (early 6.0);
0xE8
ULONG CurrentPState;
6.0  
0xB8 (early 6.0) 0x010C
ULONG Reserved0;
early 6.0  
0xBC (early 6.0);
0xA0
0x0110 (early 6.0);
0xEC
ULONG DesiredPState;
6.0  
0xC0 (early 6.0) 0x0114
ULONG Reserved1;
early 6.0  
0xC4 (early 6.0);
0xA4
0x0118 (early 6.0);
0xF0
ULONG volatile PStateIdleStartTime;
6.0  
0xC8 (early 6.0);
0xA8
0x011C (early 6.0);
0xF4
ULONG PStateIdleTime;
6.0  
0xCC (early 6.0);
0xAC
0x0120 (early 6.0);
0xF8
ULONG LastPStateIdleTime;
6.0  
0xD0 (early 6.0);
0xB0
0x0124 (early 6.0);
0xFC
ULONG PStateStartTime;
6.0  
0xB4 0x0100
ULONG DiaIndex;
late 6.0  
0xB8 0x0104
ULONG Reserved0;
late 6.0  
0xD4 (early 6.0);
0xBC
0x0128 (early 6.0);
0x0108
ULONG_PTR WmiDispatchPtr;
6.0 next at 0x34 and 0x38
0xD8 (early 6.0);
0xC0
0x0130 (early 6.0);
0x0110
LONG WmiInterfaceEnabled;
6.0 next at 0x38 and 0x40

Windows 7 and Higher

Changes since Windows 7 have mostly been a matter of inserting, redefining or appending. There has been some reordering, however: see that IdleAccounting got moved forward for Windows 8.

Offset (x86) Offset (x64) Definition Versions Remarks
0x00 0x00
PPM_IDLE_STATES *IdleStates;
6.1 and higher prevously at 0x04 and 0x08
0x04 0x08
PROC_IDLE_ACCOUNTING *IdleAccounting;
6.2 and higher previously at 0x20
0x08 (6.2) 0x10 (6.2)
PLATFORM_IDLE_ACCOUNTING *PlatformIdleAccounting;
6.2 only  
0x08 (6.1);
0x10 (6.2);
0x08
0x08 (6.1);
0x18 (6.2);
0x10
ULONGLONG IdleTimeLast;
6.1 and higher  
0x10 (6.1);
0x18 (6.2);
0x10
0x10 (6.1);
0x20 (6.2);
0x18
ULONGLONG IdleTimeTotal;
6.1 and higher  
0x18 (6.1);
0x20 (6.2);
0x18
0x18 (6.1);
0x28 (6.2);
0x20
ULONGLONG IdleTimeEntry;
6.1 and higher  
0x20 (6.1) 0x20 (6.1)
PROC_IDLE_ACCOUNTING *IdleAccounting;
6.1 only previously (with type change) at 0x20;
next at 0x04 and 0x08
0x28 (6.2);
0x20
0x30 (6.2);
0x28
ULONGLONG Reserved;
6.2 to 6.3  
ULONGLONG IdleTimeExpiration;
10.0 and higher  
0x28 0x30
UCHAR NonInterruptibleTransition;
10.0 and higher  
0x29 0x31
UCHAR PepWokenTransition;
10.0 and higher  
0x2A 0x32
UCHAR Class;
10.0 to 1511  
UCHAR EfficiencyClass;
1607 to 1803  
UCHAR HvTargetState;
1809 and higher previously at 0x014D and 0x01A1
0x2B 0x33
UCHAR SchedulingClass;
1607 to 1803  
UCHAR Reserved;
1809 to 1903  
UCHAR SoftParked;
2004 and higher  
0x2C 0x34
ULONG TargetIdleState;
10.0 and higher  
0x30 (6.2);
0x28 (6.3);
0x30
0x38 (6.2);
0x30 (6.3);
0x38
PROC_IDLE_POLICY IdlePolicy;
6.2 and higher  
0x38 (6.2);
0x30 (6.3);
0x38
0x40 (6.2);
0x38 (6.3);
0x40
PPM_IDLE_SYNCHRONIZATION_STATE volatile Synchronization;
6.2 and higher  
0x40 (6.2);
0x38 (6.3);
0x40
0x48 (6.2);
0x40 (6.3);
0x48
PROC_FEEDBACK PerfFeedback;
6.2 and higher  
0x24 (6.1);
0xA8 (6.2);
0xA0 (6.3);
0xC8
0x28 (6.1);
0xB8 (6.2);
0xB0 (6.3);
0xD8
PROC_HYPERVISOR_STATE Hypervisor;
6.1 and higher  
0x28 (6.1) 0x2C (6.1)
ULONG PerfHistoryTotal;
6.1 only  
0x2C (6.1) 0x30 (6.1)
UCHAR ThermalConstraint;
6.1 only previously at 0x40 and 0x48
0x2D (6.1) 0x31 (6.1)
UCHAR PerfHistoryCount;
6.1 only  
0x2E (6.1) 0x32 (6.1)
UCHAR PerfHistorySlot;
6.1 only  
0x2F (6.1) 0x33 (6.1)
UCHAR Reserved;
6.1 only  
0x30 (6.1);
0xAC (6.2);
0xA4 (6.3);
0xCC
0x34 (6.1);
0xBC (6.2);
0xB4 (6.3);
0xDC
ULONG LastSysTime;
6.1 and higher previously at 0x90 and 0xD0
0x34 (6.1);
0xB0 (6.2);
0xA8 (6.3);
0xD0
0x38 (6.1);
0xC0 (6.2);
0xB8 (6.3);
0xE0
ULONG_PTR WmiDispatchPtr;
6.1 and higher previously at 0xBC and 0x0108
0x38 (6.1);
0xB4 (6.2);
0xAC (6.3);
0xD4
0x40 (6.1);
0xC8 (6.2);
0xC0 (6.3);
0xE8
LONG WmiInterfaceEnabled;
6.1 and higher previously at 0xC0 and 0x0110
0x40 (6.1);
0xB8 (6.2);
0xB0 (6.3);
0xD8
0x48 (6.1);
0xD0 (6.2);
0xC8 (6.3);
0xF0
PPM_FFH_THROTTLE_STATE_INFO FFHThrottleStateInfo;
6.1 and higher  
0x60 (6.1);
0xD8 (6.2);
0xD0 (6.3);
0xF8
0x68 (6.1);
0xF0 (6.2);
0xE8 (6.3);
0x0110
KDPC PerfActionDpc;
6.1 and higher  
0x80 (6.1);
0xF8 (6.2);
0xF0 (6.3);
0x0118
0xA8 (6.1);
0x0130 (6.2);
0x0128 (6.3);
0x0150
LONG volatile PerfActionMask;
6.1 and higher  
0x88 (6.1);
0x0100 (6.2);
0xF8 (6.3);
0x0120
0xB0 (6.1);
0x0138 (6.2);
0x0130 (6.3);
0x0158
PROC_IDLE_SNAP IdleCheck;
6.1 only  
PROC_IDLE_SNAP HvIdleCheck;
6.2 and higher  
0x98 (6.1);
0x0110 (6.2);
0x0108 (6.3);
0x0130
0xC0 (6.1);
0x0148 (6.2);
0x0140 (6.3);
0x0168
PROC_IDLE_SNAP PerfCheck;
6.1 only  
PROC_PERF_SNAP PerfCheck;
6.2 to 6.3  
PROC_PERF_CHECK *PerfCheck;
10.0 to 1903  
PROC_PERF_CHECK_CONTEXT CheckContext;
2004 and higher  
0xA8 (6.1);
0x0150 (6.2);
0x0148 (6.3);
0x0134 (10.0 to 1903)
0xD0 (6.1);
0x0188 (6.2);
0x0180 (6.3);
0x0170 (10.0 to 1903)
PROC_PERF_DOMAIN *Domain;
6.1 to 1903  
0xAC (6.1);
0x0154 (6.2);
0x014C (6.3);
0x0138 (10.0 to 1903)
0xD8 (6.1);
0x0190 (6.2);
0x0188 (6.3);
0x0178 (10.0 to 1903)
PROC_PERF_CONSTRAINT *PerfConstraint;
6.1 to 1903  
0x0158 (6.2);
0x0150 (6.3);
0x013C (10.0 to 1903);
0x0158
0x0198 (6.2);
0x0190 (6.3);
0x0180 (10.0 to 1903);
0x01A8
PPM_CONCURRENCY_ACCOUNTING *Concurrency;
6.2 and higher  
0x0140 (1703 to 1903);
0x015C
0x0188 (1703 to 1903);
0x01B0
PPM_CONCURRENCY_ACCOUNTING *ClassConcurrency;
1703 and higher  
0xB0 (6.1);
0x015C (6.2);
0x0154 (6.3);
0x0140 (10.0 to 1607);
0x0144 (1703 to 1903)
0xE0 (6.1);
0x01A0 (6.2);
0x0198 (6.3);
0x0188 (10.0 to 1607);
0x0190 (1703 to 1903)
PROC_PERF_LOAD *Load;
6.1 to 1903  
0xB4 (6.1);
0x0160 (6.2);
0x0158 (6.3);
0x0144 (10.0 to 1607);
0x0148 (1703 to 1903)
0xE8 (6.1);
0x01A8 (6.2);
0x01A0 (6.3);
0x0190 (10.0 to 1607);
0x0198 (1703 to 1903)
PROC_HISTORY_ENTRY *PerfHistory;
6.1 to 1903  
0x014C (1809 to 1903);
0x0160
0x01A0 (1809 to 1903);
0x01B8
UCHAR ArchitecturalEfficiencyClass;
1809 and higher  
0x014D (1809 to 1903);
0x0161
0x01A1 (1809 to 1903);
0x01B9
UCHAR PerformanceSchedulingClass;
1809 and higher  
0x014E (1809 to 1903);
0x0162
0x01A2 (1809 to 1903);
0x01BA
UCHAR EfficiencySchedulingClass;
1809 and higher  
0x0164 (6.2);
0x015C (6.3);
0x0148 (10.0 to 1607);
0x014C (1703 to 1803);
0x014F (1809 to 1903);
0x0163
0x01B0 (6.2);
0x01A8 (6.3);
0x0198 (10.0 to 1607);
0x01A0 (1703 to 1803);
0x01A3 (1809 to 1903);
0x01BB
UCHAR GuaranteedPerformancePercent;
6.2 to 1903  
UCHAR Unused;
2004 and higher  
0x0165 (6.2);
0x015D (6.3);
0x0149 (10.0 to 1607);
0x014D (1703 to 1803)
0x01B1 (6.2);
0x01A9 (6.3);
0x0199 (10.0 to 1607);
0x01A1 (1703 to 1803)
UCHAR HvTargetState;
6.2 to 1803 next at 0x2A and 0x32
0x0166 (6.2);
0x015E (6.3);
0x014A (10.0 to 1607);
0x014E (1703 to 1803);
0x0150 (1809 to 1903);
0x0164
0x01B2 (6.2);
0x01AA (6.3);
0x019A (10.0 to 1607);
0x01A2 (1703 to 1803);
0x01A4 (1809 to 1903);
0x01BC
UCHAR Parked;
6.2 and higher  
0x0167 (6.2);
0x015F (6.3)
0x01B3 (6.2);
0x01AB (6.3)
UCHAR OverUtilitized;
6.2 to 6.3  
0x014F (1709 to 1803);
0x0151 (1809 to 1903);
0x0165
0x01A3 (1709 to 1803);
0x01A5 (1809 to 1903);
0x01BD
UCHAR LongPriorQosPeriod;
1709 and higher  
0x0152 (1809 to 1903) 0x01A6 (1809 to 1903)
USHORT LatestAffinitizedPercent;
1809 to 1903 previously ULONG at 0x0158 and 0x01AC
0x0168 (6.2);
0x0160 (6.3);
0x014C (10.0 to 1607);
0x0150 (1703 to 1803);
0x0154 (1809 to 1903)
0x01B4 (6.2);
0x01AC (6.3);
0x019C (10.0 to 1607);
0x01A4 (1703 to 1803);
0x01A8 (1809 to 1903)
ULONG LatestPerformancePercent;
6.2 to 1903  
0x016C (6.2);
0x0150 (10.0 to 1607);
0x0154 (1703 to 1803);
0x0158 (1809 to 1903)
0x01B8 (6.2);
0x01A0 (10.0 to 1607);
0x01A8 (1703 to 1803);
0x01AC (1809 to 1903)
ULONG AveragePerformancePercent;
6.2;
not 6.3;
10.0 to 1903
 
0x0170 (6.2);
0x0164 (6.3);
0x0154 (10.0 to 1607);
0x0158 (1703 to 1803)
0x01BC (6.2);
0x01B0 (6.3);
0x01A4 (10.0 to 1607);
0x01AC (1703 to 1803)
ULONG LatestAffinitizedPercent;
6.2 to 1803 next as USHORT at 0x0152 and 0x01A6
0xB8 (6.1);
0x0174 (6.2)
0xF0 (6.1);
0x01C0 (6.2)
ULONG Utility;
6.1 to 6.2  
0xBC (6.1) 0xF4 (6.1)
ULONG OverUtilizedHistory;
6.1 only  
0xC0 (6.1) 0xF8 (6.1)
ULONG volatile AffinityCount;
6.1 only  
0xC4 (6.1) 0xFC (6.1)
ULONG AffinityHistory;
6.1 only  
0x0178 (6.2) 0x01C4 (6.2)
ULONG AffinitizedUtility;
6.2 only  
0x0168 (6.3) 0x01B4 (6.3)
ULONG ExpectedUtility;
6.3 only  
0x016C (6.3) 0x01B8 (6.3)
PROC_PERF_UTILITY Utility [3];
6.3 only  
0x0158 (10.0 to 1607);
0x015C (1703 to 1903)
0x01A8 (10.0 to 1607);
0x01B0 (1703 to 1903)
ULONG RelativePerformance;
10.0 to 1903  
0x015C (10.0 to 1607);
0x0160 (1703 to 1903)
0x01AC (10.0 to 1607);
0x01B4 (1703 to 1903)
ULONG Utility;
10.0 to 1903  
0x0160 (10.0 to 1607);
0x0164 (1703 to 1903)
0x01B0 (10.0 to 1607);
0x01B8 (1703 to 1903)
ULONG AffinitizedUtility;
10.0 to 1903  

Appended for Windows 10

Offset (x86) Offset (x64) Definition Versions
0x0168 0x01B8 (10.0 to 1607);
0x01C0
union {
    ULONGLONG SnapTimeLast;
    ULONGLONG EnergyConsumed;
};
10.0 and higher
0x0170 0x01C0 (10.0 to 1607);
0x01C8
ULONGLONG ActiveTime;
10.0 and higher
0x0178 0x01C8 (10.0 to 1607);
0x01D0
ULONGLONG TotalTime;
10.0 and higher

Appended for Version 1709

Offset (x86) Offset (x64) Definition Versions
0x0180 0x01D8
POP_FX_DEVICE *FxDevice;
1709 and higher
0x0188 0x01E0
ULONGLONG LastQosTranstionTsc;
1709 and higher
0x0190 0x01E8
ULONGLONG QosTransitionHysteresis;
1709 and higher
0x0198 0x01F0
KHETERO_CPU_QOS RequestedQosClass;
1709 and higher
0x019C 0x01F4
KHETERO_CPU_QOS ResolvedQosClass;
1709 and higher
0x01A0 0x01F8
ULONG QosEquivalencyMask;
1709 to 1803
USHORT QosEquivalencyMask;
1809 and higher

The misspelling in LastQosTranstionTsc is Microsoft’s.

Appended for Version 1809

Offset (x86) Offset (x64) Definition Versions
0x01A2 0x01FA
USHORT HwFeedbackTableIndex;
1809 and higher
0x01A4 0x01FC
UCHAR HwFeedbackParkHint;
1809 and higher
0x01A5 0x01FD
UCHAR HwFeedbackPerformanceClass;
1809 and higher
0x01A6 0x01FE
UCHAR HwFeedbackEfficiencyClass;
1809 and higher
0x01A7 0x01FF
UCHAR HeteroCoreType;
1809 and higher