
Если сравнивать процессор с автомобилем, а программное обеспечение с дорогой, то Intel напоминает гоночный автомобиль, а AMD — внедорожник. Для Intel очень важен фактор оптимизации программного обеспечения под новейшие функциональные расширения, а также оптимизация с учетом параметров кэш-памяти (то есть, «качества дороги»). Компилятор или программист должен тщательно разделить информацию на блоки, размещаемые в кэш. Малейшее отклонение от этого правила дает резкое снижение эффективности использования кэш-памяти.
Скоростные характеристики процессоров от AMD изначально скромнее, но благодаря примененным алгоритмам управления кэш-памятью, они в большей степени толерантны к ситуациям, когда объем обрабатываемых порций данных неидеально коррелирует с параметрами кэш-памяти, что можно сравнить с «неровностями и ямами».
Давайте убедимся в этом, исследовав точки перегиба в графиках производительности одного из самых модерновых процессоров AMD — Ryzen 7 2700U со встроенной графикой Radeon RX Vega 10. Базисом для этой разработки станет мобильная платформа от ASUS — ноутбук X570ZD.
Условия эксперимента
Исследование производительности центрального процессора и оперативной памяти ноутбука ASUS X570ZD выполнено с помощью утилиты NCRB. Главной измеряемой характеристикой является зависимость производительности при чтении и записи блока информации от его объема: Speed=F(Size). В силу эффектов, связанных с функционированием кэш-памяти, наиболее информативным интервалом для оценки такой зависимости являются окрестности точек, соответствующих объему уровней кэш-памяти (L1, L2, L3), разделенному на количество потоков, совместно использующих данный уровень кэш-памяти согласно топологии процессора и сценарию теста.
Рис 1. Мобильный процессор AMD Ryzen 7 2700U со встроенной графикой Radeon RX Vega 10
на материнской плате ноутбука ASUS X570ZD
Для оценки влияния выбора процессорных инструкций на производительность, тесты выполнены в трех вариантах: 64-битная форма классической инструкции передачи данных MOV, 128-битная SSE-инструкция MOVAPD и 256-битная AVX-инструкция VMOVAPD. Некоторые особенности утилиты NCRB: с целью оптимизации производительности, адреса операндов для всех операций выравниваются на величину, равную размеру операнда. При тестах оперативной памяти в ходе обработки блоков, объем которых превышает объем кэш-памяти, устанавливается non-temporal (некэшируемый) статус операции. В тестах кэш-памяти по умолчанию используется temporal статус.
Результаты эксперимента
Закономерности, заслуживающие особого внимания, можно разделить на следующие категории.
Во-первых, в силу известных ограничений векторного операционного устройства процессоров Ryzen, использование 256-битных AVX-инструкций практически не дает преимущества перед 128-битными инструкциями SSE.
Во-вторых, характер зависимости скорости чтения и записи блоков данных от их объема позволяет выделить два вида точек перегиба. Регулярные точки, имеют место при X равном объему исследуемого уровня кэш-памяти.
Рис 2. Чтение с применением 128-битных инструкций SSE, исследование кэш-памяти данных L1 (32 килобайта), один поток: падение производительности в точке X=32KB, связанное с переполнением кэш, довольно незначительно, при X=56KB имеет место нерегулярная точка перегиба
Нерегулярные точки, имеют место при значениях X отличных от объема кэш-памяти. В ряде случаев, перепад производительности в регулярной точке может быть выражен достаточно слабо, что позволяет предположить наличие механизмов, нивелирующих или откладывающих эффект падения производительности вследствие переполнения кэш-памяти. В первую очередь это относится к кэш-памяти первого уровня.
Рис 3. Чтение с применением 64-битной формы классической инструкции MOV для исследования кэш-памяти данных L1 (32 килобайта), четыре потока: весьма скромные возможности базового набора инструкций x86-64 компенсируются неплохой масштабируемостью в многопоточном тесте
«Интеллектуальные надстройки» над классическим алгоритмом LRU, обеспечивающие заблаговременную загрузку востребованных данных и корректирующие политику кэширования, используются уже достаточно длительное время, вместе с тем, уровень их влияния на результаты бенчмарок кэш-памяти в исследуемом процессоре неожиданно высок.
В-третьих, для «быстрых» ресурсов, таких как кэш-память уровней L1, L2, применение классической инструкции MOV примерно вдвое медленнее, чем 128-битной SSE-инструкции MOVAPD.
Рис 4. Чтение с применением 64-битной формы классической инструкции MOV для исследования кэш-памяти L2 (512 килобайт), один поток: причиной неожиданных колебаний может быть влияние параллельных процессов, асинхронное изменение тактовой частоты ядра а также попытка интеллектуального контроллера нивелировать последствия переполнения L2
Напомним, что длительное время после появления поддержки SSE в процессорах AMD (Socket A) и до чипов поколений AM2/AM3, оптимизация этой технологии не была в приоритетах компании, в результате, применение классических инструкций x86-64 в ряде случаев обеспечивало более высокую производительность.
Рис 5. Запись с применением 128-битных инструкций SSE, исследование кэш-памяти L2 (512 килобайт), четыре потока: предполагаемая главная причина апериодических колебаний — влияние конкурирующих процессов
В свою очередь, для 32-битных процессоров, при выполнении манипуляций с 64-битными данными, руководства по оптимизации рекомендовали применение инструкций набора MMX. По результатам теста можно еще раз подтвердить преодоление «болезни роста» SSE в процессорах AMD.
В-четвертых, в тесте кэш-памяти L3, выполненном в многопоточном варианте, включение SMT (Simultaneous Multithreading, в терминах Intel — это Hyper-Threading) улучшает стабильность результатов, существенно снижая уровень апериодических колебаний, заметных на графике.
Рис 6. Запись с применением 128-битных инструкций SSE, исследование кэш-памяти L3 (4 мегабайта), один поток: действие происходит на границе кэш-памяти последнего уровня — L3 и DRAM, поэтому ступенька весьма существенна. Именно в момент переполнения L3, при X>4MB, наблюдаемые события переносятся за пределы процессорного кристалла на шину DRAM. Кроме того, оптимальным для записи в оперативную память является non-temporal или некэшируемый тип доступа, а тест кэш-памяти, как ему и положено, использует кэшируемый, поэтому падение имеет место до уровня значительно ниже производительности DRAM, демонстрируя сценарий, которого следует избегать при оптимизации программного кода
Речь идет о включении и отключении опции SMT в опциях утилиты NCRB, в результате, в обоих случаях платформа и ОС поддерживают 8 логических процессоров, а приложение использует либо все, либо только половину из них, что дает различный уровень монополизации процессора. Вариант отключения SMT в CMOS Setup не рассматривался.
Рис 7. Чтение с применением 128-битных инструкций SSE, исследование кэш-памяти L3 (4 мегабайта), восемь потоков: уровень монополизации процессора (использование SMT тестом и запуск 8 потоков по количеству логических процессоров), как и ожидалось, обеспечил достаточно стабильный график. Первое падение, в окрестности X=256KB соответствует объему L2 (512KB) разделенному на количество потоков, выполняемых одним ядром (2 потока). Вторая точка перегиба, в окрестности X=512KB соответствует объему L3 (4MB) разделенному на количество потоков, выполняемых всем процессором (8 потоков)
Устойчивой тенденцией является повышение стабильности результатов в многопоточном режиме, особенно в случае высокого уровня монополизации процессора. Можно констатировать, что для AMD этот технологический фактор перешел в разряд стратегических.
В-пятых, топология кэш-памяти оказывает определяющее влияние на производительность многопоточных бенчмарков. Поскольку кэш-память уровней L1 и L2 является приватным ресурсом каждого из ядер, при обработке информации, размещаемой в пределах L1 и L2, теоретически, производительность должна масштабироваться в соответствии с количеством ядер исследуемого процессора, равном 4, поскольку конкуренция за доступ к данным отсутствует. На практике, значение мультипликатора составляет 2.8...3.1. Причиной этого могут быть механизмы термоконтроля, ограничивающие тактовую частоту при возрастании энергопотребления вследствие высокой загрузки CPU.
В-шестых, в отличие от L1 и L2, кэш-память уровня L3 общая для всего процессорного кристалла, это создает конкуренцию при доступе потоков к данным, объем которых превышает L2 и означает снижение уровня параллелизма. Вместе с тем, для тестов, основанных на классической инструкции MOV, показатели которых в большей степени ограничены выполнением процессорных инструкций, чем трафиком L3, уровень параллелизма (но не абсолютное значение скорости!) может оставаться достаточно высоким, несмотря на конкурентный доступ к L3.
Резюме
Если, как мы предполагаем, кэш-контроллер действительно собирает статистику об обращениях программы к памяти (и делает это более интеллектуально, чем конкуренты), то это шанс увеличить производительность консервативного софта, не оптимизированного под требования конкретной платформы. А, как известно, консервативный софт — традиционно сильная сторона AMD.
Когда-то революционный набор инструкций IA-64 (Intel Architecture 64, Itanium), подразумевающий «явный параллелизм», то есть тщательное планирование выполняемой работы на этапе компиляции, проиграл более консервативной эволюционной архитектуре x86-64.