AMD EPYC и vSphere vNUMA

Grigory Pryalukhin
Sep 26 · 12 min read

Это перевод статьи Frank Denneman AMD EPYC и vSphere vNUMA.
Публикуется с разрешения автора.

Да, я знаю, что уже доступно второе поколение процессоров EPYC, но нужно начинать с начала. Фрэнк сказал, что уже работает над статьей про Rome, будем ждать от него новостей. А пока разберемся с особенностями Naples.

AMD набирает популярность на серверном рынке с EPYC CPU платформой. EPYC CPU платформа предоставляет высокое количество ядер и большой объем памяти. Если вы знакомы с предыдущим поколением AMD, то знаете, что AMD придерживается других принципов работы, нежели Intel. Для справки посмотрите статью, которую я писал в 2011 о 12-core 6100 Opteron под кодовым именем Magny-Cours. EPYC предоставляет больший масштаб, используя ранее представленные принципы. Давайте рассмотрим EPYC архитектуру и посмотрим, как она влияет на сайзинг ВМ и настройки ESXi. (Целью этой статьи не является сравнение AMD и Intel и оценка, что лучше, я хочу описать архитектурные различия).

EPYC архитектура

EPYC процессорная архитектура это то, что AMD называет Multi-Chip-Module (MCM). EPYC создан для того, чтобы предоставить большое число ядер за счет объединения нескольких кремниевых кристаллов в одном корпусе. Кремниевый кристалл (названный Zeppelin) это полупроводниковая пластина, которая содержит интегральные микросхемы. Это компонент, который содержит CPU ядра, кэш память и различные контроллеры. Независимо от числа ядер корпус процессор EPYC всегда содержит четыре Zeppelin кристалла. Сравним его с Intel Xeon. Процессор Xeon имеет архитектуру Single-Chip-Design и всего один кремниевый кристалл, содержащий все компоненты. Причина, по которой интересна разница в архитектуре процессоров, заключается в том, что архитектура влияет на логическую группировку вычислительных ресурсов. Размер логической группы, более известной как NUMA узел, влияет на принятие решений планировщика процессора операционной системы (и самого гипервизора, и, возможно, гостевой операционной системы). Возможно потребуется изменить некоторые настройки по умолчанию для ESXi хоста, чтобы изменить поведение планировщика. Эти параметры будут описаны в последней части статьи. Давайте продолжим исследовать архитектуру EPYC процессора.

AMD EPYC — image courtesy of wccftech.com

Compute Complex

На фото выше представлена структура процессора. В процессоре находятся четыре Zeppelin кристалла. В текущем поколении Zeppelin кристалл содержит максимум восемь Zen ядер. Все ядра разделены на два Compute Complex (CCX). Zeppelin 32 ядреного EPYC содержит 4 ядра в каждом CCX. Когда технология Simultaneous Multi-Threading (SMT) включена в BIOS, CCX предоставляет восемь потоков.

Zeppelin CCX Layout of 32 Core EPYC

Каждое ядро имеет свой собственный L1 (инструкции (64KB) и данные (32KB)) и L2 кэш (всего 4MB L2 кэша). Zeppelin имеет 16MB L3 кэша. Интересно, что каждый CCX имеет собственный L3 кэш объемом 8MB, который, в свою очередь разделен на 4 части по 2MB. Два CCX в кристалле Zeppelin соединены друг с другом через интерконнект (Infinity Fabric). Добавление хопов при доступе к памяти невыгодно с точки зрения пропускной способности и задержек. Несколько технических порталов произвели серьезное тестирование производительности кэша и по словам Anandtech.com:

“Локальный, находящийся внутри CCX 8MB L3 кэш доступен с очень низкими задержками. Но как только ядру необходимо получить доступ к другой части L3 кэша, находящемся даже на том же кристалле, задержка становится достаточно высока, она лишь немного лучше, чем задержка доступа к DRAM.”

По сути, это означает, что вы не можете считать все 64MB L3 кэша единым пулом ресурсов кэш памяти. Лучше считать, что вы имеете восемь 8MB пула кэш памяти. Это важно понимать, если несколько рабочих нагрузок совместно используют одни и те же данные, а планировщик ESXi пытается разместить обе рабочие нагрузки в одном и том же NUMA узле, чтобы оптимизировать производительность кэша и памяти для этих рабочих нагрузок. Может так случиться, что размер L3 может быть недостаточен. Опция, влияющая на это поведение, называется Action Affinity, более подробную информацию об этом параметре можно найти в последней части статьи.

Количество ядер Zeppelin

EPYC доступен для заказа по нескольким SKU. Кроме модели с 32 ядрами, существуют модели с меньшим количеством ядер. Поскольку архитектура EPYC всегда содержит четыре Zeppelin, изменения количества ядер достигается путем симметричного отключения ядер в каждой CCX. Например, в 24 ядерном EPYC один Zeppelin кристалл будет выглядеть следующим образом.

Zeppelin design of 24 Core EPYC

В таблице ниже показано количество ядер на Zeppelin для трех самых больших EPYC процессоров. Общее количество ядер на каждом Zeppelin кристалле можно использовать в качестве ориентира для настройки vNUMA, описанной далее в этой статье.

┌───────┬───────────────┬────────────────────┬────────────────┐
│ Cores │ Cores per CCX │ Cores per Zeppelin │ Zeppelin Count │
├───────┼───────────────┼────────────────────┼────────────────┤
│ 32 │ 4 │ 8 │ 4 │
│ 24 │ 3 │ 6 │ 4 │
│ 16 │ 2 │ 4 │ 4 │
└───────┴───────────────┴────────────────────┴────────────────┘

Infinity Fabric

Ядра внутри CCX взаимодействуют с памятью (DIMM) через встроенный в кристалл контроллер памяти, используя Infinity Fabric. Infinity Fabric — это проприетарная технология интерконнеста AMD, которая обеспечивает передачу данных и управление всеми связанными компонентами. Infinity Fabric состоит из двух communication planes: Scalable Data Fabric (SDF) и Infinity Scalable Control Fabric (SCF). SCF отвечает за обработку сигналов управления системой, таких как управление температурой и питанием. Это конечно очень важно, но для нас больше интересен SDF, ответственный за передачу данных в системе. Остальная часть статьи фокусируется на дизайне SDF и его влиянии на работу планировщика.

Каждый CCX подключен к SDF через Cache-Coherent Master (CCM), который отвечает за пересылку когерентного (согласованного) трафика между CCX. SDF использует Unified Memory Controller (UMC) для подключения к DRAM модулям памяти. Каждый UMC предоставляет канал памяти для двух модулей DIMM. Обеспечивая работу четырех DIMM модулей памяти.

Zeppelin CCX and SDF Architecture

Как это влияет на сайзинг виртуальной машины? Zeppelin кристалл — это NUMA узел, который содержит максимум 8 ядер (16 потоков) и суммарный объем памяти, сформированный 4 модулями DIMM. Таким образом, один EPYC процессор предоставляет четыре NUMA узла операционной системе.

Объем оперативной памяти и NUMA

Intel перешла от конфигурации с 3 модулями DIMM на канал (DIMMs per channel configuration (DPC)) и 4 каналами, к конфигурации с 6 каналами и 2 модулями DIMM. Это новая модель сломала привычный порядок. Например, используя 16GB модули памяти, вам может быть доступно 64GB, 128GB или 192GB памяти на каждый сокет. Теперь, с

Scalable архитектурой это либо 96GB или 192GB памяти. Это означает, что следуя best practice для высокой производительности, необходимо заполнение всех каналов для обеспечения максимальной пропускной способности. Однако при нынешней цене DIMM многие клиенты не могут позволить себе такую конфигурацию.

В EPYC, каждый Zeppelin имеет два канала памяти. Каждый канал поддерживает до двух модулей. Для хорошей производительности каждый канал должен быть укомплектован хотя бы одним модулем DIMM. Это означает, что хорошо спроектированная (с точки зрения производительности) система должна иметь 16 модулей памяти. Такая конфигурация обеспечивает теоретическую пропускную способность 42,6GB/s, обеспечивая при этом (небольшую) емкость памяти только двух модулей DIMM. В результате один EPYC процессор презентует четыре NUMA узла операционной системе. Если используется минимальное количество модулей памяти на канал — один (1DPC), размер NUMA узла может быть слишком мал и, следовательно, мала общая производительность, если размер виртуальной машины превышает объем памяти, доступной каждому Zeppelin. Servethehome опубликовали benchmark тесты о различиях производительности между разными конфигурациями памяти для EPYC.

1 EPYC CPU Package = 4 NUMA Nodes

Для NUMA очень важно понимать границы локальной памяти и удаленной памяти. Традиционно это легко разграничивалось по количеству ядер процессора и объему подключенной памяти. При использовании EPYC необходимо также понимать различие между типами удаленного доступа к памяти. Это может быть удаленный доступ к памяти внутри одного процессора или удаленный доступ к памяти другого процессора (сокета). Причина, по которой необходимо понимать эту разницу, заключается во влиянии на скорость доступа к памяти приложений. Наличие виртуальной машины и приложения, занимающих несколько NUMA узлов, может привести к очень нестабильному времени отклика.

Доступ к локальной памяти

Давайте начнем с лучшего и наиболее стабильного в плане производительности варианта. Когда ядро работает с локальной памятью Zeppelin, путь данных выглядит следующим образом:

Local Memory Access

Презентация AMD “Zeppelin an SOC for Multi-Chip Architectures” сообщает, что задержка доступа к локальной памяти составляет 90 наносекунд.

Удаленный доступ к памяти внутри одного процессора

Ядро может получить доступ к памяти, подключенной к другому Zeppelin в пределах одного и того же процессора. Это называется — удаленный внутрипроцессорный доступ к памяти или “on-package Die-to-Die” доступ к памяти. Это означает, что мы все еще используем контроллеры памяти одного сокета. Всего процессор EPYC имеет восемь каналов памяти, но только два являются локальными для Zeppelin. Для доступа к “удаленному” внутрипроцессорному контроллеру памяти Infinity Fabric On Package Controller (IFOP) устанавливает и координирует передачу данных.

В общей сложности каждый Zeppelin имеет 4 IFOP, но нужны на самом деле только три, поскольку в каждом процессоре есть только еще три Zeppelin.

Если быть точнее, IO проходит через еще один компонент, прежде чем попасть в IFOP. Этот компонент называется Coherent AMD socKet Extender (CAKE). Это облегчает кристалл-кристалл (die-to-die) или сокет-сокет (socket-to-socket) доступ к памяти. Этот модуль переводит запросы и ответы в формат, используемый SDF транспортным уровнем, в последовательный формат, используемый IFOP. Это означает, что при доступе к данным, хранящимся в модулях DIMM, подключенным к другим Zeppelin внутри одного процессора, требуется дополнительные хопы и процессорные циклы. AMD говорит, что задержка в таком случае составит ~145ns.

Remote Memory Access within EPYC CPU

Межпроцессорный удаленный доступ

И наконец есть шанс, что данные должны быть извлечены из модулей DIMM, подключенных к UMC, из Zeppelin, который является частью другого процессора EPYC (двухсокетная система). Вместо маршрутизации трафика через IFOP, трафик направляется через контроллер Infinity Fabric Inter Socket (IFIS). Трафик процессор-процессор имеет 8/9 от полосы пропускания IFOP, соответственно теоретическая полоса пропускания составит 37,9GB/s. Ограничение полосы пропускания может вызывать понижение производительности. Удлинение пути увеличивает и задержки. AMD говорит о задержке ~200ns.

Поскольку каждый Zeppelin имеет два IFIS контроллера, не каждый Zeppelin в двухсокетной системе подключен друг к другу напрямую. В худшем варианте будет два хопа. Первый хоп от одного процессора к другому и дополнительный хоп от одного Zeppelin к другому Zeppelin, к которому подключен модуль DIMM, содержащий данные. К сожалению, AMD не поделилась информацией о такой задержке.

Remote Access Inter-package, die-to-die communication

Сайзинг ВМ

Ключевым является стремление, чтобы доступ к памяти был максимально локальным, насколько это возможно. ESXi и большинство современных гостевых операционных систем оптимизированы для работы с NUMA. Однако, как и для большинства вещей в жизни, для хорошей производительности требуется уменьшить расстояние и сократить вариативность. Примените это к сайзингу ВМ и постарайтесь вместить количество vCPU виртуальной машины в количество ядер NUMA домена. То же самое относится и к объему памяти, постарайтесь вместить его в объем NUMA узла. Если ВМ помещается в NUMA узел, нет необходимости расстраиваться, ESXi имеет лучший NUMA планировщик. Чтобы помочь ESXi оптимизироваться под EPYC архитектуру, могут понадобиться дополнительные advanced настройки. Как всегда, тестируйте эти настройки в безопасной для доходов компании среде, а потом переносите в прод.

Virtual NUMA

Virtual NUMA (vNUMA) позволяется операционной системе понимать “физическую” топологию виртуальной машины. vNUMA определяет мапинг vCPU ВМ на физические NUMA узлы ESXi хоста. Например, если виртуальная машина имеет 12 vCPU, а количество физических ядер в одном NUMA узле 10, то ESXi предоставит гостевой ОС топологию из двух узлов NUMA, каждый из которых будет содержать по 6 ядер. ESXi будет группировать по 6 vCPU в NUMA клиента и “планировать” (schedule) их для 10 ядер NUMA узла.

Когда была представлена vNUMA, наибольшее количество ядер процессора было равно 8, поэтому инженеры VMware установили пороговое значение vNUMA равное 9 (numa.vcpu.min=9). Это означает, что ВМ должна иметь по крайней мере 9 vCPU для создания virtual NUMA топологии. Учитывая, что наибольшее число ядер в системе EPYC составляет восемь ядер на Zeppelin, вы можете настроить стандартное пороговое значение vNUMA, чтобы оно было похоже на физическую топологию используемой модели EPYC.

Например, EPYC 7401 содержит 24 ядра, 6 ядер на Zeppelin и, таким образом, 6 ядер на NUMA узел. Когда вы используете стандартные настройки numa.vcpu.min=9, ВМ с 8 vCPU автоматически настраивается вот так.

Screenshot by @AartKenens

VPD — это virtual NUMA клиент, который воздействует на гостевую ОС, в то время как PPD — это NUMA клиент, который использует планировщик CPU VMkernel. В этой ситуации, планировщик ESXi использует два физических NUMA узла для удовлетворения запросов ВМ к процессору и памяти, в то время как гостевая ОС воспринимает топологию как Uniform Memory Access (UMA) систему. В UMA системе время доступа к памяти не зависит от того какой процессор делает этот запрос или какой чип содержит запрашиваемые данные, т.е. во всей системе примерно одинаковые задержки и пропускная способность. Тем не менее, это не наш кейс. Чтение и запись из удаленного CCX кэша и удаленной памяти (даже внутри одного процессора) медленнее, чем из локальной памяти внутри одного Zeppelin. Если задать параметр numa.vcpu.min=6, то создадутся два VPD и гостевая ОС получит информацию о физической топологии хоста. Гостевая ОС и приложения смогут оптимизировать работу с памятью для достижения лучшей производительности.

Action Affinity

Когда планировщик ESXi обнаружит несколько ВМ, взаимодействующих друг с другом, он может решить разместить их вместе на одном и том же узле NUMA, что увеличит скорость intra-NUMA взаимодействия. Такое поведение называется Action Affinity, и оно может увеличивать производительность до 30%. Однако, при небольших узлах NUMA, максимум по 8 CPU, это может привести к значительному перерасходу кэша и удаленному доступу к памяти, если объем памяти ВМ превышает объем одного узла NUMA. В этом случае может быть полезно попробовать отключить Action Affinity на ESXi хосте. Это делается путем установки параметра /Numa/LocalityWeightActionAffinity в значение 0 (KB 2097369).

Что если настроенный объем памяти ВМ превышает объем памяти физического узла NUMA?

Я писал об этом еще в 2017 и такая ситуация описана в книге vSphere 6.5 Host deep dive. Однако, что произойдет если настроенный объем памяти ВМ превысит физический объем NUMA узла. По умолчанию планировщик ESXi оптимизирован для локального доступа к памяти и попытается разместить максимум памяти принадлежащей vCPU в том же самом NUMA узле. Иногда создание нескольких меньших NUMA клиентов может улучшить локальный доступ к памяти.

Например, EPYC 7601 (32 ядра), NUMA узел содержит 8 ядер, и сервер укомплектован 256ПИ (16 x 16GB DIMM). NUMA узел имеет 4 модуля DIMM. Таким образом, NUMA узел содержит 8 ядер и 64GB. Что произойдет, если ВМ будет настроена с 6 vCPU и 96GB? По умолчанию планировщик ESXi попытается разместить 64GB памяти ВМ внутри NUMA узла, оставшиеся 32GB в удаленном NUMA узле. Включив advanced настройку numa.consolidate = FALSE заставит планировщик распределить ВМ между оптимальным количеством NUMA узлов, большим чем 1. В этом случае будут созданы два NUMA узла, и планировщик распределит по 3 vCPU в каждый NUMA узел.

Теперь производительность и поведение приложения зависит от его архитектуры. Если приложение однопоточное, этот параметр может оказаться бесполезным. Однако, если это многопоточное приложение, вы можете заметить некоторые преимущества. Единственное, что нужно сделать, это установить параметр numa.vcpu.min в значение равное количеству vCPU в каждом virtual NUMA клиенте, чтобы определить топологию vNUMA для гостевой ОС и для приложения. Следующая команда поможет вам получить NUMA конфигурацию виртуальной машины:

vmdumper -l | cut -d \/ -f 2-5 | while read path; do egrep -oi “DICT.(displayname.|numa.|cores.|vcpu.|memsize.|affinity.)= .|numa:.|numaHost:.” “/$path/vmware.log”; echo -e; done

Помните, что планировщик CPU и NUMA в ESXi не использует SRAT (System Resource Allocation Table) для определения дистанции между отдельными NUMA узлами. ESXi использует свой собственный метод для определения задержки между различными узлами NUMA в системе. ESXi использует значения этих задержек для первоначального размещения и пытается разместить NUMA клиентов ВМ максимально близко друг к другу. Однако планировщик ESXi не использует эту информацию во время балансировки нагрузки. Эта работа ведётся. Добавление нового первоклассного показателя в эвристику — непростая задача, и, зная инженеров CPU, они стремятся создать систему, которая будет полностью улучшена за счет дополнения нового кода.

Увеличение NUMA Node Compute Sizing

Для рабочих нагрузок, чувствительных к задержкам доступа к памяти, при низкой утилизации процессора, вы можете изменить способ, согласно которому планировщик NUMA устанавливает размер NUMA клиента для каждой конкретной ВМ. Advanced параметр ВМ numa.vcpu.preferHT=TRUE позволяет NUMA планировщику считать потоки вместо ядер для настройки размера узла NUMA. Например, ВМ с 8 vCPU, к которой применен этот параметр и запущенная на EPYC 7401 (6 ядер, 12 потоков), работает внутри одного Zeppelin.

Если все рабочие нагрузки соответствуют одному и тому же паттерну нагрузки, вы можете изменить настройку целиком ESXi хоста, добавив advanced параметр numa.PreferHT=1.

Channel-Pair Interleaving (1 NUMA узел на сокет)

Архитектура EPYC может уплотнять каналы памяти, позволяя презентовать ядра четырех Zeppelin как один NUMA узел. Эта настройка требует, чтобы каждый канал памяти был заполнен одинаковым объемом. Некоторые вендоры используют разные названия для этой настройки. Например, Dell “Memory Die Interleaving”. Данные о влиянии этого параметра на производительность практически отсутствуют, но имейте в виду, что настройки программного обеспечения не изменят физическую топологию (и, следовательно, физику). Обычно результаты обобщены и отображают среднюю производительность. Для сравнительного анализа производительности NUMA ознакомьтесь со статьей “AMD EPYC — STREAM, HPL, InfiniBand, and WRF Performance Study”, расположенной на сайте Dell.

Исследуйте ваши требования к рабочим нагрузкам

ESXi может очень хорошо обрабатывать сложные NUMA архитектуры. Однако лучше максимально избегать сложных конфигураций пока это возможно. Определите может ли ваша рабочая нагрузка соответствовать максимальному количеству небольших NUMA узлов при использовании EPYC? Может ли рабочая нагрузка обрабатывать несогласованную производительность памяти, если она превышает размер узла NUMA, равный 8? Архитектура EPYC является отличным способом добавления масштабируемости серверной платформе, но помните, что для реальной рабочей нагрузки оптимальная производительность достигается только с учетом размера NUMA.

В Twitter спрашивают, что я думаю об архитектуре процессора EPYC? Для каждой технической проблемы есть решение. Если посмотреть на архитектуру, я думаю, что EPYC — отличное решение для небольших и средних рабочих нагрузок. Я думаю, что для более крупных монолитных приложений, требующих постоянной производительности, будет лучше посмотреть на другие архитектуры. (Это мое мнение, а не мнение VMware!)

Grigory Pryalukhin

Written by

Все, что здесь публикуется является моим персональным мнением. Не является мнением или позицией моих прошлых, текущих или будущих работодателей.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade