
У AMD нет заоблачных продаж в серверном сегменте. Тем не менее, новые процессоры EPYC нашли путь к сердцу потребителей. Но цена на серверные чипы AMD не могла стать определяющим фактором без приемлемого уровня функциональности: компания вторглась на рынок, где высокую планку поставил Intel.
Сравнивая две архитектуры, эксперты приводят в пример плотность процессорных ядер на одно процессорное гнездо. У Intel Xeon это 28 ядер, у AMD EPYC – на 4 больше. Насколько хорошо справились разработчики с эффективной реализацией столь насыщенного решения? Тестирование односокетной серверной платформы ASUS KNPA-U16, оснащенной EPYC 7351Pдает возможность понять, чем взял процессор от AMD.
Комплексное решение
Корпус процессора AMD EPYC (проект Naples) содержит четыре кристалла, каждый из которых разделен на два кластера CCX (Core Complex). Каждый из таких кластеров, в свою очередь, в зависимости от модели процессора, может содержать до четырех вычислительных ядер. В случае применения SMT-технологии, каждое ядро может быть представлено двумя логическими процессорами.
Рис 1. NUMA-топология процессора AMD EPYC: кристалл, разделенный на два кластера, изображен справа
Исходя из топологии Naples, вычислим количество логических процессоров в максимальной конфигурации односокетной платформы:
- 4 кристалла на процессор
- 2 кластера CCX на кристалл
- 4 вычислительных ядра на CCX-кластер
- 2 потока на ядро, при условии использования SMT
Перемножив топологические параметры, получим 64 логических процессора. Платформа с AMD EPYC 7351P 16-Core Processor, побывавшая в нашей тестовой лаборатории, обладает более скромными параметрами – 32 логических процессора.
Топологическая иерархия
Если уровни кэш-памяти L1 и L2 являются приватными ресурсами каждого из ядер, то объем кэш-памяти третьего уровня для процессора AMD EPYC 7351P 16-Core Processor определен как 64 мегабайта на процессорный корпус, иными словами на сокет.
Рис 2. Для процессоров AMD суммарный объем кэш-памяти L3 многокристальной процессорной микросхемы, определяется с помощью функции CPUID 80000006h
Несмотря на такую формулировку, часто используемую в популярных описаниях, речь не идет о наличии единого запоминающего пространства такого размера. Вместо этого, каждый из CCX-кластеров содержит собственный блок L3-кэш, размером 8 МБ.
Рис 3. Для процессоров AMD объем кэш-памяти L3, приходящейся на CCX-кластер, определяется с помощью функции CPUID 8000001Dh
По сравнению с монолитным, преимуществами такого решения является снижение уровня конкуренции при доступе вычислительных ядер к L3-кэш и снижение латентности, вследствие уменьшения топологического расстояния.
Исследование кластеризации L3
и эффектов на границе L3/DRAM
Попробуем экспериментально проверить поведение кэш-памяти L3-уровня, рассмотрев эффекты производительности на границе с DRAM. Намеренно создав для процессора «неудобные условия» выполнения однопоточного кода, убедимся в том, что один обрабатываемый поток располагает только 8 МБ локальной кэш-памяти L3.
В силу того, что запись в память классической инструкцией MOV не использует non-temporal оптимизацию, а потому кэшируется, тест оперативной памяти с ее применением наглядно демонстрирует эффект присутствия L3.
Рис 4. Запись в оперативную память без non-temporal оптимизации: один поток задействует один CCX-кластер одного NUMA-домена
Как видим, переполнение кэш-памяти L3 наступает при объеме обрабатываемого блока около 8 МБ. Итак, оптимальная утилизация ее полного объема, составляющего 64 МБ, возможна только в многопоточном коде, при участии всех CCX-кластеров.
Рис 5. Запись в оперативную память с non-temporal оптимизацией: один поток задействует один CCX-кластер одного NUMA-домена, участие кэш-памяти нивелировано
Поставленный эксперимент потребовал тщательного подбора условий, ведь если запись в память выполняется более производительными инструкциями SSE (MOVNTPD) – значит, с non-temporal оптимизацией – «ступеньку», обусловленную влиянием кэш-памяти, увидеть не удастся.
О памяти
Из приведенного выше скриншота следует, что скорость обмена с оперативной памятью у процессора AMD EPYC 7351P составляет около 32 GBPS. Для двухканального контроллера памяти эта цифра вполне соответствует ожиданиям. Но ведь топология Naples предполагает оснащение каждого из четырех кристаллов процессора EPYC собственным двухканальным DRAM-контроллером.
Оценим теоретическую пропускную способность оперативной памяти в сумме для всего процессорного гнезда. Для этого потребуется перемножить эффективную частоту передачи данных (в нашем примере 2.4 ГГц), количество байт на один DRAM-канал (64 бита = 8 байт) и количество каналов.
2.4 GHz * 8 bytes per channel * 8 channels = около 153.6 GBPS
Критерий оптимальности требует, чтобы каждый из параллельно работающих логических процессоров, взаимодействовал с оперативной памятью, обращаясь к ближайшему с точки зрения топологии DRAM-контроллеру – в нашем примере к тому, который находится с ним на одном кристалле. Тогда конкуренция за использование трафика ОЗУ между потоками будет минимальной, а маршрут доступа — кратчайшим. Иными словами, нужно минимизировать количество транзакций, пересекающих границы NUMA-доменов.
NUMA-оптимизация в представлении Microsoft
Для выделения памяти с явным указанием оптимального домена в операционных системах Microsoft предлагается использовать функцию VirtualAllocExNuma. Для ограничения множества процессоров, используемых операционной системой при выполнении заданного потока или группы потоков, есть функция SetThreadAffinityMask.
Применяя две указанные WinAPI-функции, программист устанавливает соответствие между диапазонами памяти и использующими их потоками в пределах одного NUMA-домена, чтобы вычислительное ядро обращалось к ближайшему DRAM-контроллеру. Исключение – обмен информацией между потоками. Удельный вес таких операций для оптимального алгоритма может быть некритичным.
Отметим, что реализация указанных функций подразумевает рекомендательный характер. Нехватка памяти на заданном оптимальном NUMA-домене приведет к использованию памяти в другом месте. Это может дать нерегулярное, а потому трудно выявляемое снижение производительности.
Кроме того, для полной утилизации возможностей систем, содержащих более 64 логических процессоров, потребуется отдельный редизайн приложений. Владельцы односокетных платформ с AMD EPYC на борту по этому поводу могут не волноваться, а вот серверы с двумя и более процессорами для полной утилизации своих ресурсов потребуют особой совместимости прикладного ПО.
Почему? Потому что в архитектуре функций WinAPI такой важный параметр как affinity mask, определяющий участие логических процессоров в заданной операции, изначально был определен как битовый вектор, фиксированной размерности – 64 бита. Поддержка большего количества процессоров требует разделения ресурсов SMP-платформы на группы (Processor Groups), в каждой из которых их может быть не более чем 64 устройства (не имеет значения, физических или логических). При этом программное обеспечение, написанное без учета этого факта, может использовать процессоры только одной группы.
Резюме
Для любой платформы, построенной в соответствии с принципами NUMA, требуется оптимизация программного обеспечения. Этот тезис, очевидный для систем на базе процессоров Intel и AMD, можно расширить и на все вычислительные платформы. Вместе с тем «цена» неоптимального доступа зависит от того, насколько обмен с оперативной памятью «чужого» домена медленнее по сравнению с доступом к ОЗУ «своего» домена. Другими словами – метрикой производительности может стать дистанция между доменами.
Рис 6. Сравнение реализации процессора в виде монолитного кристалла (Monolithic Die)
и многокристальной конструкции EPYC Multichip module
Для платформ с двумя (еще хуже – четырьмя) процессорными гнездами оптимизация маршрутов к ОЗУ выглядит нетривиальной задачей. Дополнительную турбулентность в логику теперь вносят несколько процессорных чипов в одном сокете. Различие в производительности оптимизированного и не оптимизированного софта для них весьма заметно. В этом свете понятно желание AMD упростить жизнь интеграторам, предложив пусть и не универсальное, но достаточно мощное односокетное решение – EPYC 7xx1P.