KeQueryNodeActiveAffinity2-Funktion (wdm.h)
Diese Routine gibt die aktuelle Multigruppenprozessoraffinität des angegebenen NUMA-Knotens zurück.
Syntax
NTSTATUS KeQueryNodeActiveAffinity2(
[in] USHORT NodeNumber,
[out] PGROUP_AFFINITY GroupAffinities,
[in] USHORT GroupAffinitiesCount,
[out] PUSHORT GroupAffinitiesRequired
);
Parameter
[in] NodeNumber
Stellt die Knotennummer des zu abfragenden Knotens bereit.
[out] GroupAffinities
Stellt einen Zeiger auf ein Array von GROUP_AFFINITY Strukturen bereit, die nach Erfolg eine Gruppennummer und die Affinitätsmaske der identifizierten Gruppe erhalten.
[in] GroupAffinitiesCount
Ein Wert vom Typ USHORT, der die Anzahl der Elemente im Gruppenaffinitätsarray angibt. Wenn das Array zu klein ist, um die Knotenaffinität zu halten, wird STATUS_BUFFER_TOO_SMALL zurückgegeben, und die Anzahl der erforderlichen Elemente wird in GroupAffinitiesRequiredzurückgegeben.
[out] GroupAffinitiesRequired
Ein Zeiger auf einen Wert vom Typ USHORT, der die Anzahl der Gruppenaffinitäten empfängt, die erforderlich sind, um die Knotenaffinität darzustellen. Bei einem nur speichergeschützten NUMA-Knoten wird Null zurückgegeben.
Rückgabewert
STATUS_SUCCESS, wenn die Knotenaffinität erfolgreich abgefragt wurde.
STATUS_INVALID_PARAMETER, wenn eine ungültige Knotennummer angegeben wurde.
STATUS_BUFFER_TOO_SMALL, wenn das angegebene Array zu klein ist.
Bemerkungen
Ab Windows Server 2022 teilt das Betriebssystem keine großen NUMA-Knoten mehr auf. Stattdessen meldet Windows die wahre NUMA-Topologie des Systems. Wenn ein Knoten mehr als 64 Prozessoren enthält, erstreckt sich ein NUMA-Knoten über mehr als eine einzelne Gruppe. In diesem Fall weist das System für jeden NUMA-Knoten eine primäre Gruppe zu. Die primäre Gruppe ist immer die Gruppe, die die meisten Prozessoren enthält. Um die Anzahl der aktiven Prozessoren in einem bestimmten NUMA-Knoten (über alle Gruppen hinweg) zu ermitteln, rufen Sie KeQueryNodeActiveProcessorCountauf. Weitere Informationen zu dieser Verhaltensänderung finden Sie unter NUMA Support.
Um das Verhalten der älteren Knotenaufteilung erneut zu aktivieren, nehmen Sie die folgende Änderung an der Registrierung vor, und starten Sie das System neu:
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NUMA" /v SplitLargeNodes /t REG_DWORD /d 1
Wenn Ihr Treiber Prozessoren NUMA-Knoten zugeordnet, indem sie KeQueryNodeActiveAffinity-aufrufen und Ihr Code auf Systemen mit mehr als 64 Prozessoren pro NUMA-Knoten ausgeführt wird, verwenden Sie eine der folgenden Problemumgehungen:
Migrieren Sie zu den Affinitäts-APIs mit mehreren Gruppen (Benutzermodus und Kernelmodus), z. B. KeQueryNodeActiveAffinity2.
Rufen Sie KeQueryLogicalProcessorRelationship mit RelationNumaNode- auf, um den NUMA-Knoten, der einer bestimmten Prozessornummer zugeordnet ist, direkt abzufragen.
Das folgende Beispiel zeigt Code, der unter Windows Server 2022 und höher problematisch wäre, und zeigt dann beide Problemumgehungen an.
//
// 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];
}
Anforderungen
Anforderung | Wert |
---|---|
mindestens unterstützte Server- | Windows Server 2022 |
Header- | wdm.h |
IRQL- | Beliebige Ebene |