KeQueryNodeActiveAffinity2 函式 (wdm.h)
這個例程會傳回指定NUMA節點目前的多群組處理器親和性。
語法
NTSTATUS KeQueryNodeActiveAffinity2(
[in] USHORT NodeNumber,
[out] PGROUP_AFFINITY GroupAffinities,
[in] USHORT GroupAffinitiesCount,
[out] PUSHORT GroupAffinitiesRequired
);
參數
[in] NodeNumber
提供要查詢之節點的節點編號。
[out] GroupAffinities
提供 GROUP_AFFINITY 結構陣列的指標,此陣列會在成功時收到已識別群組的群組編號和親和性遮罩。
[in] GroupAffinitiesCount
USHORT 類型的值,指定群組親和性陣列中的項目數目。 如果陣列太小而無法保存節點親和性,則會傳回 STATUS_BUFFER_TOO_SMALL ,並在 GroupAffinitiesRequired 中傳回所需的元素數目。
[out] GroupAffinitiesRequired
USHORT 類型的值指標,可接收代表節點親和性所需的群組親和性數目。 如果是僅限記憶體的 NUMA 節點,則會傳回零。
傳回值
STATUS_SUCCESS 是否已成功查詢節點親和性。
如果指定了無效的節點編號,STATUS_INVALID_PARAMETER。
如果 提供的陣列太小,STATUS_BUFFER_TOO_SMALL。
備註
從 Windows Server 2022 開始,操作系統不再分割大型 NUMA 節點;相反地,Windows 會報告系統真正的 NUMA 拓撲。 當節點包含超過 64 個處理器時,NUMA 節點會跨越多個群組。 在此情況下,系統會為每個NUMA節點指派主要群組。 主要群組一律是包含最多處理器的群組。 若要判斷指定 NUMA 節點中作用中處理器的數目, (所有群組) ,請呼叫 KeQueryNodeActiveProcessorCount。 如需此行為變更的詳細資訊,請參閱 NUMA 支援。
若要重新啟用舊版節點分割行為,請對登錄進行下列變更,並重新啟動系統:
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NUMA" /v SplitLargeNodes /t REG_DWORD /d 1
如果您的驅動程式藉由呼叫 KeQueryNodeActiveAffinity 將處理器對應至 NUMA 節點,而且您的程式代碼會在每個 NUMA 節點超過 64 個處理器的系統上執行,請使用下列其中一個因應措施:
移轉至多群組節點親和性 API, (使用者模式和內核模式) ,例如 KeQueryNodeActiveAffinity2。
使用 RelationNumaNode 呼叫 KeQueryLogicalProcessorRelationship,以直接查詢與指定處理器編號相關聯的 NUMA 節點。
下列範例顯示 Windows Server 2022 和更新版本上可能會有問題的程式代碼,然後顯示這兩個因應措施。
//
// Problematic implementation using KeQueryNodeActiveAffinity.
//
USHORT CurrentNode;
USHORT HighestNodeNumber;
GROUP_AFFINITY NodeAffinity;
ULONG ProcessorIndex;
PROCESSOR_NUMBER ProcessorNumber;
HighestNodeNumber = KeQueryHighestNodeNumber();
for (CurrentNode = 0; CurrentNode <= HighestNodeNumber; CurrentNode += 1) {
KeQueryNodeActiveAffinity(CurrentNode, &NodeAffinity, NULL);
while (NodeAffinity.Mask != 0) {
ProcessorNumber.Group = NodeAffinity.Group;
BitScanForward(&ProcessorNumber.Number, NodeAffinity.Mask);
ProcessorIndex = KeGetProcessorIndexFromNumber(&ProcessorNumber);
ProcessorNodeContexts[ProcessorIndex] = NodeContexts[CurrentNode;]
NodeAffinity.Mask &= ~((KAFFINITY)1 << ProcessorNumber.Number);
}
}
//
// Resolution using KeQueryNodeActiveAffinity2.
//
USHORT CurrentIndex;
USHORT CurrentNode;
USHORT CurrentNodeAffinityCount;
USHORT HighestNodeNumber;
ULONG MaximumGroupCount;
PGROUP_AFFINITY NodeAffinityMasks;
ULONG ProcessorIndex;
PROCESSOR_NUMBER ProcessorNumber;
NTSTATUS Status;
MaximumGroupCount = KeQueryMaximumGroupCount();
NodeAffinityMasks = ExAllocatePool2(POOL_FLAG_PAGED,
sizeof(GROUP_AFFINITY) * MaximumGroupCount,
'tseT');
if (NodeAffinityMasks == NULL) {
return STATUS_NO_MEMORY;
}
HighestNodeNumber = KeQueryHighestNodeNumber();
for (CurrentNode = 0; CurrentNode <= HighestNodeNumber; CurrentNode += 1) {
Status = KeQueryNodeActiveAffinity2(CurrentNode,
NodeAffinityMasks,
MaximumGroupCount,
&CurrentNodeAffinityCount);
NT_ASSERT(NT_SUCCESS(Status));
for (CurrentIndex = 0; CurrentIndex < CurrentNodeAffinityCount; CurrentIndex += 1) {
CurrentAffinity = &NodeAffinityMasks[CurrentIndex];
while (CurrentAffinity->Mask != 0) {
ProcessorNumber.Group = CurrentAffinity.Group;
BitScanForward(&ProcessorNumber.Number, CurrentAffinity->Mask);
ProcessorIndex = KeGetProcessorIndexFromNumber(&ProcessorNumber);
ProcessorNodeContexts[ProcessorIndex] = NodeContexts[CurrentNode];
CurrentAffinity->Mask &= ~((KAFFINITY)1 << ProcessorNumber.Number);
}
}
}
//
// Resolution using KeQueryLogicalProcessorRelationship.
//
ULONG ProcessorCount;
ULONG ProcessorIndex;
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX ProcessorInformation;
ULONG ProcessorInformationSize;
PROCESSOR_NUMBER ProcessorNumber;
NTSTATUS Status;
ProcessorCount = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS);
for (ProcessorIndex = 0; ProcessorIndex < ProcessorCount; ProcessorIndex += 1) {
Status = KeGetProcessorNumberFromIndex(ProcessorIndex, &ProcessorNumber);
NT_ASSERT(NT_SUCCESS(Status));
ProcessorInformationSize = sizeof(ProcessorInformation);
Status = KeQueryLogicalProcessorRelationship(&ProcessorNumber,
RelationNumaNode,
&ProcessorInformation,
&ProcessorInformationSize);
NT_ASSERT(NT_SUCCESS(Status));
NodeNumber = ProcessorInformation.NumaNode.NodeNumber;
ProcessorNodeContexts[ProcessorIndex] = NodeContexts[NodeNumber];
}
規格需求
需求 | 值 |
---|---|
最低支援的伺服器 | Windows Server 2022 |
標頭 | wdm.h |
IRQL | 任何層級 |