Freigeben über


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:

  1. Migrieren Sie zu den Affinitäts-APIs mit mehreren Gruppen (Benutzermodus und Kernelmodus), z. B. KeQueryNodeActiveAffinity2.

  2. 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

Siehe auch

KeQueryNodeActiveAffinity

KeQueryNodeActiveProcessorCount

NUMA Support-