Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Эта подпрограмма возвращает текущее сходство обработчика с несколькими группами заданного узла 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
Если драйвер сопоставляет процессоры с узлами NUMA путем вызова KeQueryNodeActiveAffinity, а код выполняется в системах с более чем 64 процессорами на узел NUMA, используйте одно из следующих обходных решений:
Миграция на api сопоставления узлов с несколькими группами (режим пользователя и режим ядра), например KeQueryNodeActiveAffinity2.
Вызовите KeQueryLogicalProcessorRelationship с RelationNumaNode для прямого запроса узла 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 | Любой уровень |