Поддержка NUMA
Традиционная модель для многопроцессорной поддержки - симметричная многопроцессорная система (SMP). В этой модели, каждый процессор имеет равный доступ к памяти и вводу - выводу (I/O). Поскольку добавляется большее количество процессоров, шина процессора становится ограничением для эффективности системы.
Системные проектировщики теперь используют
неоднородный доступ к памяти (NUMA), чтобы увеличить быстродействие процессора без увеличения нагрузки на шине процессора. Архитектура неоднородна потому, что каждый процессор находится близко к некоторым частям памяти и дальше от других частей памяти. Процессор быстро получает доступ к памяти, которая рядом, в то время как может потребоваться больше времени, чтобы получить доступ к памяти, которая находится дальше.В NUMA системе, ЦПУ размещаются в меньших системах называемых узлы
(nodes). Каждый узел имеет свои собственный процессор и память и подключается к большей системе через КЭШ - когерентную связь с шиной.Система пытается улучшать эффективность, включая в график потоки на процессорах, которые находятся в том же самом узле как используемая память. Она пытается удовлетворять запросы распределения памяти внутри узла, но выделяет память и для других узлов в случае необходимости. Вы можете улучшать производительность приложения при помощи использования функции NUMA, чтобы улучшить диспетчеризацию и использование памяти.
Прежде всего, Вам нужно будет установить компоновку узлов в системе. Чтобы получить самый высокий пронумерованный узел в системе, используйте функцию
GetNumaHighestNodeNumber.Обратите внимание! на то, что это число не гарантирует равенство с общим количеством узлов в системе. К тому же, узлы с последовательными числами, не гарантируют, что он находятся рядом друг с другом. |
Чтобы извлечь список процессоров в системе, используйте функцию GetProcessAffinityMask. Вы можете установить узел для каждого процессора в списке при помощи использования функция GetNumaProcessorNode. Или же, чтобы получить список всех процессоров в узле, используйте функцию GetNumaNodeProcessorMask.
После того, как Вы выяснили, какие процессоры принадлежат каким узлам, Вы можете оптимизировать эффективность вашего приложения. Чтобы убедиться, что все потоки вашего процесса запускаются на одном и том же узле, используйте функцию SetProcessAffinityMask с маской родственного процесса, которая устанавливает процессоры на том же самом узле. Это увеличивает эффективность прикладных программ, потокам которой нужно обращаться к той же самой памяти. Или же, чтобы ограничить число потоков на каждом узле, используйте функцию SetThreadAffinityMask.
Прикладным программам, интенсивно использующим память, нужно оптимизировать их использование памяти. Чтобы получить объем памяти, доступный узлу, используйте функцию
GetNumaAvailableMemoryNode. Или же, чтобы выяснить узел для заданного диапазона памяти, используйте функцию NumaVirtualQueryNode.