Кэш-память L3 как зеркало производительности процессора AMD EPYC Rome

Оценивая быстродействие кэш-памяти тре­тье­го уров­ня, ре­а­ли­зо­ван­ной на крис­тал­ле про­цес­со­ра AMD EPYC 7452, мы стол­к­ну­лись с си­ту­а­ци­ей, тре­бу­ю­щей де­таль­но­го рас­смот­ре­ния. Преж­де чем, за­нять­ся ее ана­ли­зом, из­у­чим осо­бен­нос­ти ор­га­ни­за­ции L3-кэш у се­мей­ст­ва про­цес­со­ров EPYC Rome, раз­ра­бо­тан­ных с ис­поль­зо­ва­ни­ем ар­хи­тек­ту­ры Zen 2.

Собственно, L3 не является составной частью архитектуры процессорного ядра Zen 2. Классический подход к раз­ра­бот­ке со­вре­мен­ных про­цес­со­ров об­ще­го наз­на­че­ния ограничивает возможности ядра кэш-памятью пер­во­го и вто­ро­го уров­ней. Но Zen 2 на третьем уровне для кэширования инструкций и данных формует сущность CCX (Compute Com­plex), в которую может быть погружено 4 процессорных ядра. Они совместно используют блок кэш-памяти L3 объ­е­мом 16 МБ. Пара таких комплексов составляет чиплет CCD — за­ме­ча­тель­ное изо­бре­те­ние AMD. Всего может быть до 8 та­ких чип­ле­тов, что дает основание говорить о наличии максимум 256 МБ кэш-памяти L3.

В случае 32-ядерного EPYC 7452, в основе которого лежат 4 чиплета CCD, кэш-память третьего уровня ограничена 128 ме­га­бай­та­ми.

Топологическая иерархия AMD Rome

Топологическая иерархия AMD Rome

Анализируем CPUID

Исходя из сказанного, чисто теоретически, в распоряжении одного ядра может находиться не более 16 МБ L3, а в ус­ло­ви­ях реальной эксплуатации — и того меньше. Проверим вышесказанное, с по­мо­щью утилиты Java CPUID.

Параметры комплекса CCX согласно результатам выполнения инструкции CPUID, функция 8000001Dh

Параметры комплекса CCX согласно результатам выполнения инструкции CPUID, функция 8000001Dh

CPUID функция 8000001Dh позволяет получить информацию о кэш-памяти одного комплекса CCX. Каждое его яд­ро ос­на­ще­но L1-кэшем для инструкций и данных объемом по 32 килобайта каждый; объем кэш-памяти L2 со­став­ля­ет 512 килобайт. При этом L1 и L2 являются ресурсами приватными для каждого из ядер. Заметим, что места в L1-кэш для инструкций в процессорах второго поколения AMD EPYC выделено в два раза мень­ше, чем было в первом поколении этих сер­вер­ных чипов.

Параметр Max. logical CPUs sharing this cache для L1 и L2 равен двум — это количество ло­ги­че­ских про­цес­со­ров, со­в­мест­но ис­поль­зу­ю­щих L1 и L2, что с учетом технологии SMT означает: два логических CPU со­от­вет­ст­ву­ют одному ядру. Для L3-кэш этот параметр равен 8 — количество ядер, совместно использующих блок L3, равно 4.

Суммарный объем кэш-памяти L3 на одно процессорное гнездо (согласно CPUID функции 80000006h)

Суммарный объем кэш-памяти L3 на одно процессорное гнездо (согласно CPUID функции 80000006h)

Чтобы определить полный объем L3 для процессора, воспользуемся CPUID функцией 80000006h. Эта ве­ли­чи­на со­став­ля­ет 128 MB — топология L3 представлена восемью кластерами по 16 MB. Данные CPUID фун­к­ции 8000001Dh говорят о том, что ассоциативность L3 (Ways of associativity) равна 16. На скриншоте функции 80000006h значение L3 Unified Cache Associativity находится в состоянии Reserved, что следует из офи­ци­аль­ной до­ку­мен­та­ции.

Обратим также внимание на параметр L2 data TLB for 4KB pages number of entries, который равен 800h, что в де­ся­тич­ном пред­став­ле­нии дает 2048; он нам понадобится позже.

L3 Unified Cache Associativity

 

До сих пор считалось, что 16-вариантной ас­со­ци­а­тив­но­сти соответствует значение битового поля EDX.[15-12], равное 8. В нашем случае CPUID возвращает 9, что может означать или за­паз­ды­ва­ние в до­ку­мен­та­ции, или особое ар­хи­тек­тур­ное решение.

Из маркетинговых материалов AMD следует, что латентность L3 в процессорах семейства EPYC 7002 обусловлена временем, соответствующим 40 процессорным тактам (для предыдущего семейства Naples это зна­че­ние бы­ло не­сколь­ко ниже — латентность L3-кэш составляла 35 тактов), что хорошо согласуется с данными, полученными в ходе эксперимента.

Измерение латентности в этом эксперименте основано на идее ис­поль­зо­ва­ния про­чи­тан­ных дан­ных в ка­че­ст­ве ад­ре­са для сле­ду­ю­ще­го чтения. При этом подавляются спекулятивные способности CPU, по­сколь­ку не­воз­мож­но опе­ре­жа­ю­щее вы­пол­не­ние сле­ду­ю­ще­го чтения, искажающее результат. Процесс связан с доступом к фраг­мен­ти­ро­ван­ным дан­ным с ран­до­ми­за­ци­ей адресов, поэтому каждая следующая операция с высокой ве­ро­ят­но­стью бу­дет опе­ри­ро­вать с но­вой стра­ни­цей и потребует загрузки нового дескриптора в TLB. Метрики мы будем получать с помощью своего программного продукта, предназначенного для измерения про­из­во­ди­тель­ности кэш и оперативной памяти — утилиты NUMA CPU and RAM Benchmark (сокращенно NCRB).

Про страницы, TLB и латентность L3-кэш

Как известно, механизм трансляции страниц (или paging) отображает виртуальное ад­рес­ное про­ст­ран­ст­во при­ло­же­ния на фи­зи­че­скую память платформы. Каждая страница описывается дескриптором Page Table Entry (PTE). За кэ­ши­ро­ва­ние таких дескрипторов отвечает блок Translation Lookaside Buffer (TLB).

Классическая схема, принятая еще во времена i386, гранулирует оперативную память четырех килобайтными стра­ни­ца­ми, что хотя и экономно, но связано с серьезными накладными расходами в современных условиях. Се­го­дня до­сту­пен и один из продвинутых способов — гра­ну­ляр­ность «большими страницами», размером в 2 МБ. Вы­го­ды от его ис­поль­зо­ва­ния очевидны: в большинстве приложений растет эффективность операций с ОЗУ.

Терминологическое уточнение

В нашем эксперименте ОС предоставляет, а бенчмарк NCRB использует большие страницы, формируемые пу­тем про­пус­ка одного подкаталога страниц (PTE), действующего на последней стадии трансляции ли­ней­но­го адреса в фи­зи­че­ский. Вы­сво­бож­да­е­мые при этом адресные биты становятся частью адреса байта вну­три страницы. В про­цес­сор­ной ар­хи­тек­ту­ре x­64 (а также в IA32 + PAE) это увеличивает размер страницы до 2 MB, в IA32 это уве­ли­чи­ва­ет раз­мер стра­ни­цы до 4 MB. Как сказано выше, стандартные страницы со времен п­роцессора i386, всегда имеют размер 4 KB.

Буфер ассоциативной трансляции

И хотя польза от «больших страниц» иногда сомнительна, с переходом в режим Large Pages раз­мер ад­ре­су­е­мой об­лас­ти уве­ли­чи­ва­ет­ся с 4 KB (Normal Pages) до 2 MB (Large Pages), а количество выделенных для этого де­ск­рип­то­ров про­пор­ци­о­наль­но умень­ша­ет­ся. В результате снижается нагрузка на TLB — один из важнейших уровней кэш-памяти, ко­то­рый сме­ло мож­но на­звать «серым кардиналом» производительности. Рассмотрим влияние бу­фе­ра ас­со­ци­а­тив­ной тран­сля­ции на латентность кэш-памяти L3-уровня в процессоре EPYC 7452.

TLB и латентность L3-кэш

Вернувшись к иллюстрации результатов функции CPUID 80000006h, приведенной в начале статьи, об­ра­тим вни­ма­ние на L2 data TLB for 4KB pages number of entries. Согласно CPUID, объем бу­фе­ра ас­со­ци­а­тив­ной тран­сля­ции, кэширующего де­ск­рип­то­ры страниц, составляет 800h = 2048 элементов. Они позволяют ад­ре­со­вать «нормальными» 4 KB стра­ни­ца­ми ди­а­па­зон па­мя­ти в 2048 * 4KB = 8192K = 8MB.

Размер кластера L3-кэша, обслуживающего 4 процессорных ядра CCX, вдвое превышает эту границу. Вы­пол­ним од­но­по­точ­ное тес­ти­ро­ва­ние латентности L3, чтобы оценить зависимость этого параметра от спо­со­ба тран­сля­ции стра­ниц оперативной памяти.

На графиках латентности меньшие значения соответствуют бо́льшей производительности

Зависимость латентности однопоточного доступа от объема обрабатываемого блока в окрестности общего пространства L3 = 16MB одного кластера CCX в режиме Normal Pages

Зависимость латентности однопоточного доступа от объема обрабатываемого блока в окрестности общего пространства L3 = 16MB одного кластера CCX в режиме Normal Pages

Логично предположить, что на графике латентности L3 в режиме 4KB страниц, точка перегиба при X = 8 MB вызвана исчерпанием L2 Data TLB, это приводит к TLB-промахам и необходимости читать дескрипторы из ОЗУ, что, очевидно, займет значительно больше тактов, чем получение их из TLB. Далее, в окрестности X = 16 MB происходит исчерпание объема кластера L3, что также сопровождается точкой перегиба.

Зависимость латентности однопоточного доступа от объема обрабатываемого блока в окрестности общего пространства L3 = 16MB одного кластера CCX в режиме Large Pages

Зависимость латентности однопоточного доступа от объема обрабатываемого блока в окрестности общего пространства L3 = 16MB одного кластера CCX в режиме Large Pages

В данном примере использование Large Pages почти нивелирует влияние фактора TLB на результат теста. Что и по­нят­но: «большие страницы» позволяют адресовать диапазон памяти в 2048 * 2MB = 4096MB = 4GB, хотя при этом в ис­сле­ду­е­мом процессоре количество элементов L2 TLB для обычных и больших страниц совпадает.

В силу особенностей страничной трансляции, при расчетах объемов данных, вызывающих переполнение TLB, ключевое значение имеет не раз­мер собственно дескриптора страницы, а размер диапазона памяти, до­ступ к ко­то­ро­му обеспечивает один де­ск­рип­тор.

Пропускная способность L3-кэш

В отличие от латентности пропускная способность измеряется на операциях с достаточно большими и не­пре­рыв­ны­ми бло­кам дан­ных. Здесь, один раз попав на страницу, бенчмарк гарантированно прочитает или за­пи­шет (в за­ви­си­мос­ти от ти­па тес­та) весь объем страницы, прежде чем перейти к следующей.

Сказанное означает, что частота промахов TLB в тестах пропускной способности должна быть ниже, чем в тестах ла­тен­т­нос­ти, значит, к фактору Large Pages измерения латентности должны быть более чув­ст­ви­тель­ны, чем из­ме­ре­ния про­пус­к­ной спо­соб­но­с­ти.

На графиках пропускной способности бо́льшие значения соответствуют бо́льшей производительности

Зависимость однопоточной скорости чтения от объема обрабатываемого блока в окрестности общего пространства L3 = 16MB одного кластера CCX в режиме Normal Pages

Зависимость однопоточной скорости чтения от объема обрабатываемого блока в окрестности общего пространства L3 = 16MB одного кластера CCX в режиме Normal Pages

Зависимость однопоточной скорости чтения от объема обрабатываемого блока в окрестности общего пространства L3 = 16MB одного кластера CCX в режиме Large Pages

Зависимость однопоточной скорости чтения от объема обрабатываемого блока в окрестности общего пространства L3 = 16MB одного кластера CCX в режиме Large Pages

Вместе с тем, опыт продемонстрировал, что оба показателя (латентность и пропускная способность) не ли­ше­ны влияния фактора TLB. Заметим, что в силу специфики нашего примера читаемый блок помещается в кэш-память исследуемого уровня (объемом 16MB), а картирующий контекст, необходимый для обслуживания операции чтения в режиме 4KB страниц не помещается в TLB (объем которого позволяет адресовать диапазон размером 8MB).

Подводя итоги

В ситуации, когда процессорные ядра достигли частотного порога насыщения, а их количество напрямую не может оп­ре­де­лять производительность всего вычислительного комплекса, решающее значение имеет ос­на­ще­ние CPU ум­ны­ми ал­го­рит­ма­ми, где не последнее место отводится алгоритмам кэширования. В про­цес­со­рах семейства AMD Rome кроме приватных кэш-ресурсов L1 и L2 на первых ролях агрегирований L3-кэш. Его задача — обес­пе­чить про­из­во­ди­тель­ность CCX-кластера в частности и всего процессора в целом, а так­же снизить нагрузку на подсистему DRAM, об­слу­жи­ва­е­мую от­дель­ным крис­тал­лом I/O Hub.

Проведенный эксперимент продемонстрировал зависимость даже в од­но­по­точ­ном ре­жи­ме про­пуск­ной спо­соб­но­с­ти и ла­тен­т­нос­ти L3 от механизма трансляции линейного адреса в физический. Стоит предполагать, что при муль­ти­по­точ­ном ис­поль­зо­ва­нии L3 задержки при доступе к этому раз­де­ля­е­мо­му ресурсу быст­ро­дей­ст­ву­ю­щей па­мя­ти будут на­рас­тать.

В основе обнаруженного феномена — зависимость от объема и организации буфера ассоциативной трансляции. Не­труд­но за­ме­тить, что ситуация, при которой данные обрабатываемого блока помещаются в кэш-памяти, а кар­ти­ру­ю­щий контекст, необходимый для трансляции его страниц не помещается в TLB (в режиме 4K стра­ниц), характерна для блоков, объем которых сравним с объемом L3. В этой ситуации роль TLB ста­но­вит­ся критически важной. Про­тес­ти­ро­ван­ный про­цес­сор AMD EPYC 7452 32-Core доказал это.

Как следует из графиков латентности, в режиме Large Pages имеет место полуторакратное снижение ве­ли­чи­ны за­дер­жки при доступе к L3 при объеме блока X=16MB. Этот факт заслуживает внимания разработчиков коммерческого про­грам­мно­го обес­пе­че­ния, от­вет­ст­вен­но относящихся к оптимизации кода — сценарий нашего синтетического теста мо­де­ли­ру­ет доступ к фраг­мен­ти­ро­ван­ным данным. Несмотря на все сложности внедрения «больших страниц», их ис­поль­зо­ва­ние в при­клад­ных за­да­чах (сис­те­мы уп­рав­ле­ния ба­за­ми дан­ных и т.п.) вы­гля­дит оп­рав­да­но с точ­ки зре­ния борь­бы за каж­дую на­но­се­кун­ду про­цес­сор­но­го вре­ме­ни.