company_banner

Профилировка гибридных кластерных приложений MPI+OpenMP



    Библиотеки, реализующие стандарт MPI (Message Passing Interface) — наиболее популярный механизм организации вычислений на кластере. MPI позволяет передавать сообщения между узлами (серверами), но никто не мешает запускать несколько MPI процессов и на одном узле, реализуя потенциал нескольких ядер. Так часто и пишутся HPC приложения, так проще. И пока количество ядер на одном узле было мало, никаких проблем с «чистым MPI» подходом не было. Но сегодня количество ядер идёт на десятки, а то и на сотни для со-процессоров Intel Xeon-Phi. И в такой ситуации запуск десятков процессов на одной машине становится не совсем эффективным.

    Дело в том, что MPI процессы общаются через сетевой интерфейс (хоть и реализованный через общую память на одной машине). Это влечет за собой избыточные копирования данных через множество буферов и увеличенный расход памяти.

    Для параллельных вычислений внутри одной машины с общей памятью гораздо лучше подходят потоки и распределение задач между ними. Здесь наибольшей популярностью в мире HPC пользуется стандарт OpenMP.

    Казалось бы – ладно, используем OpenMP внутри узла, и MPI для меж-узловых коммуникаций. Но не всё так просто. Использование двух фреймворков (MPI и OpenMP) вместо одного не только несёт дополнительную сложность программирования, но и не всегда даёт желаемый прирост производительности – по крайней мере, не сразу. Нужно ещё решить, как распределить вычисления между MPI и OpenMP, и, возможно, решить проблемы, специфичные для каждого уровня.

    В этой статье я не буду описывать создание гибридных приложений – информацию найти не сложно. Мы рассмотрим, как можно анализировать гибридные приложения с помощью инструментов Intel Parallel Studio, выбирая оптимальную конфигурацию и устраняя узкие места на разных уровнях.

    Для тестов будем использовать NASA Parallel Benchmark:
    • CPU: Intel Xeon processor E5-2697 v2 @ 2.70GHz, 2 сокета, 12 ядер в каждом.
    • OS: RHEL 7.0 x64
    • Intel Parallel Studio XE 2016 Cluster Edition
    • Компилятор: Intel Compiler 16.0
    • MPI: Intel MPI library 5.1.1.109
    • Workload: NPB 3.3.1, “CG — Conjugate Gradient, irregular memory access and communication” module, class B

    Бенчмарк уже реализован гибридным и позволяет конфигурировать количество MPI процессов и OpenMP потоков. Понятно, что для меж-узловых коммуникаций альтернативы MPI тут нет (в рамках нашего приложения). Интрига в том, что запускать на одном узле – MPI или OpenMP.

    MPI Performance Snapshot


    У нас в распоряжении 24 ядра. Начнём с традиционного подхода – только MPI. 24 MPI процесс, по 1 потоку на каждый. Для анализа программы воспользуемся новым инструментом, вышедшим в последней версии Intel Parallel Studio – MPI Performance Snapshot. Просто добавляем ключ “-mps” в строку запуска mpirun:
    source /opt/intel/vtune_amplifier_xe/amplxe-vars.sh
    source /opt/intel/itac/9.1.1.017/intel64/bin/mpsvars.sh --vtune
    mpirun -mps –n 24 ./bt-mz.B.24
    mps -g stats.txt app_stat.txt _mps
    

    Первые две строки выставляют нужное окружение, третья запускает программу с профилировкой MPS. Последняя строка формирует отчёт в формате html. Без -g отчёт будет выведен на консоль – удобно для просмотра сразу на кластере, но в HTML красивее:




    MPS даёт верхнеуровневую оценку производительности. Накладные расходы на его запуск крайне малы, можно быстро сделать оценку приложения даже на больших масштабах (протестировано 32000 процессов).

    Для начала смотрим доли MPI time и Computation time. У нас 32% времени уходит на MPI, почти всё из-за дисбаланса нагрузки – одни процессы ждут, пока другие считают. В блоках справа приводится оценка – время MPI помечено HIGH – слишком много тратиться на коммуникацию. Там же есть отсылка к другому инструменту – Intel Trace Analyzer and Collector (ITAC), для детального анализа MPI проблем. Про OpenMP никаких проблем не подсвечено, что неудивительно, ведь мы его фактически выключили.

    MPS также считает аппаратные метрики эффективности: GFPLOS, CPI и метрику “Memory Bound” – общую оценку эффективности работы с памятью. А ещё потребление памяти (для одного MPI процесса) – максимальное и среднее.

    Intel Trace Analyzer and Collector


    MPS показал, что основная проблема в конфигурации “24х1” в MPI. Для выяснения причин собираем профиль ITAC:
    source /opt/intel/itac/9.1.1.017/intel64/bin/itacvars.sh
    mpirun -trace -n 24 ./bt-mz.B.24
    

    Открываем трассу в ITAC GUI – я пользовался Windows версией. На графике Quantitative Timeline отчётливо видно, что доля MPI велика, и коммуникации распределены с некоторой цикличностью. Самый верхний график показывает периодические всплески MPI активности:



    Если выделить несколько таких всплесков на шкале Event Timeline, можно наблюдать, что коммуникации распределены неравномерно. Процессы с рангами 0-4 больше считают, а с рангами 15-23 больше ждут. Дисбаланс нагрузки налицо:



    На графике Message Profile можно оценить, какие именно процессы обмениваются сообщениями и где коммуникация наиболее долгая:



    Например, дольше других проходят сообщения между процессами с рангами 17 и 5, 16 и 0, 18 и 7, и т.д. Увеличив ещё сильнее Event Timeline, можно кликнуть по чёрной линии на 17-м ранге и посмотреть детали пересылки – от кого кому, размер сообщения, вызовы отправки и получения:



    Панель Performance Assistant описывает конкретные проблемы, найденные инструментом в выделенном регионе. Например, «поздняя отсылка»:



    Дисбаланс в MPI может быть вызван не только недостатками в коммуникационной схеме, но и проблемами в полезных вычислениях – когда одни процессы считают медленнее других. Если мы заинтересовались, на что это приложение тратит время внутри какого-то из процессов, и в чём могут быть проблемы, ITAC может сгенерировать командную строку для запуска Intel VTune Amplifier для этого ранга (например, на 2-го):




    Но к VTune Amplifier вернёмся позже. Да и вообще, ITAC даёт массу возможностей для детального исследования MPI коммуникаций, но наша задача сейчас – выбрать оптимальный баланс между OpenMP и MPI. А для этого необязательно сразу исправлять MPI коммуникации на 24-х рангах – можно для начала попробовать другие варианты.

    Другие варианты





    Итак, эмпирическим путём получилось, что распределения 12х2 и 6х4 работают лучше других. Даже 2 OpenMP потока на каждый процесс существенно быстрее, чем 2 MPI процесса. Однако, с ростом числа потоков время работы снова начинает расти: 2х12 ещё хуже, чем «чистый MPI», а 1х24 даже приводить нет смысла. И виной всему дисбаланс работы, которая плохо распределяется по большому количеству OpenMP потоков. Вариант 2х12 имеет аж 30% дисбаланса.

    Здесь мы вполне может остановиться, т.к. достигнутый компромисс 12х2 или 6х4 вполне приемлем. Но можно и копнуть глубже — поисследовать, в чём проблема с OpenMP масштабированием.

    VTune Amplifier


    Для детального анализа проблем OpenMP отлично подойдёт Intel VTune Amplifier XE, о чём мы уже писалиподробно.
    source /opt/intel/vtune_amplifier_xe/amplxe-vars.sh
    mpirun -gtool "amplxe-cl -c advanced_hotspots -r my_result:1" -n 24 ./bt-mz.B.24
    

    Для запуска анализаторов, таких как VTune Amplifier и Intel Advisor XE, стало очень удобно пользоваться синтаксисом опции gtool (только в Intel MPI). Она встраивается в строку запуска MPI приложения, позволяя запускать анализ лишь на выбранных процессах – в нашем примере только для ранга 1.

    Посмотрим на профиль варианта “2 MPI процесса, 12 OpenMP потоков”. В одном из наиболее затратных параллельных циклов 0.23 секунды из 1.5 уходит на дисбаланс. Дальше в таблице видно, что тип диспетчеризации статический, перераспределения работы не происходит. Кроме того, в цикле всего 41 итерация, а в соседних циклах 10-20 итераций. Т.е. при 12 потоках каждому достанется всего 3-4 итерации. Видимо, этого не достаточно для эффективного баланса нагрузки.



    При 2-4 потоках каждому из них достаётся больше работы, и относительное время активного ожидания, вызванного дисбалансом, снижается. Что подтверждается профилем “6х4” – imbalance значительно ниже:



    Кроме того, в версии Intel VTune Amplifier 2016 появилось время MPI – колонка «MPI Communication Spinning» и жёлтая разметка на временной шкале. Можно запустить профиль VTune сразу для нескольких процессов на одном узле, и наблюдать MPI spinning вместе с OpenMP метриками в каждом из них:




    Intel Advisor XE


    Спускаясь ниже по уровням параллелизма, от масштаба кластера (MPI), до потоков одного узла (OpenMP) добираемся до параллелизма по данным внутри одного потока – векторизации, основанной на SIMD инструкциях. Здесь тоже может быть серьёзный потенциал для оптимизации, однако не зря мы добрались до него в последнюю очередь – сначала нужно решить проблемы на уровнях MPI и OpenMP, т.к. там потенциально можно больше выиграть. Про Advisor не так давно было два поста (первый и второй), поэтому здесь я ограничусь строкой запуска:
    source /opt/intel/advisor_xe/advixe-vars.sh
    mpirun -gtool "advixe-cl -collect survey --project-dir ./my_proj:1" -n 2 ./bt-mz.2
    

    Дальше проводим анализ векторизации кода, как мы писали раньше. Advisor составляет важную часть экосистемы анализа кластерных MPI программ. Кроме глубокого исследования векторизации кода, Advisor помогает прототипировать многопоточное исполнение и проверяет шаблоны доступа к памяти.

    Резюме


    Intel Parallel Studio предлагает четыре инструмента для анализа производительности гибридных HPC приложений:
    • MPI Performance Snapshot (уровень кластера) — быстрая оценка эффективности, минимальные накладные расходы, профилировка до 32000 MPI процессов, быстрая оценка дисбаланса MPI и OpenMP, общая оценка производительности (GFLOPS, CPI).
    • Intel Trace Analyzer and Collector (уровень кластера) – детальное исследование MPI, выявление шаблонов коммуникации, локализация конкретных узких мест.
    • Intel VTune Amplifier XE (уровень одного узла) – детальный профиль с исходным кодом и стэками, дисбалансы и другие проблемы OpenMP, анализ использования кэша и памяти и многое другое.
    • Intel Advisor XE (уровень одного узла) – анализ использования векторных инструкций и выявление причин их неэффективности, прототипирование многопоточного исполнения, анализ шаблонов доступа к памяти.

    • +20
    • 5.1k
    • 2
    Intel
    158.09
    Company
    Share post

    Comments 2

      +1
      В резюме хотелось бы видеть не список инструментов Intel, а вывод: в каких случаях подходит MPI, а в каких OpenMP (с цифрами результатов работы бенчмарков)
        0
        Согласен, это было бы интересно. Но здесь нет единого рецепта, иначе бы я его может и описал. Выбор «MPI или OpenMP», и особенно «сколько ранков и сколько потоков» пускать, зависит от приложения, и по-хорошему надо прогнать сотню гибридных приложений, и вывести статистику результатов. Это отдельная большая работа, за рамками этого поста.

      Only users with full accounts can post comments. Log in, please.