Повышение производительности коллективных операций MPICH2

advertisement
Повышение производительности коллективных операций MPICH2
Александр Владимирович Гришагин
Нижегородский государственный университет им. Н. И. Лобачевского, Нижний Новгород
Введение
Распространенность кластерных установок в мире параллельного аппаратного обеспечения, а так же
невысокая стоимость и простота построения приводят к огромному
количеству разнообразных
конфигураций. Фактически, каждый кластер в некотором роде «уникален», кроме тех, которые специально
разрабатываются и продаются единым комплексом. Ещё большее разнообразие вносит программное
обеспечение: известно, например, что смена версий ядра Linux может изменить коммуникационные
задержки вплоть до 2-х раз. Такое разнообразие в производительности, и, более того, отсутствие
стабильности в производительности должно учитываться при создании средств параллельного
взаимодействия, ведь разные режимы передачи для «больших» и «маленьких» сообщений появляются почти
повсеместно. При определении того, что есть «большое» и «маленькое», обычно господствует голая
эмпирика (показательна в этом смысле работа [1]). Ясно, что проблема это достаточно общая, и необходимо
вырабатывать общие подходы к её решению. В данной работе указанные проблемы рассматриваются на
примере коллективных операций в библиотеке MPICH2 (http://www-unix.mcs.anl.gov/mpi/mpich2/)
Алгоритмы коллективных операций в MPICH2
Библиотека MPICH2 использует несколько алгоритмов для каждой коллективной операции. Например,
в MPI_Bcast есть три способа разослать «всем» сообщение. Это бинарное дерево, рассылка частей
сообщения и последующий сбор, а так же кольцевая рассылка (подробнее см. [1]). При этом в исходный код
MPI_Bcast жестко зашит механизм выбора алгоритма для рассылки: для размера сообщения менее 12К
всегда используется бинарное дерево (независимо от размера коммуникатора), для размера коммуникатора
более 8 и объема данных менее 512К используется рассылка частей и последующий сбор, а для данных
больше 512К – кольцевая рассылка.
Естественно, раз и навсегда запрограммированная схема никогда не покажет наилучшей
производительности. Поэтому было принято решение добавить в библиотеку MPICH2 механизмы выбора
наилучшего алгоритма для каждого вызова коллективной операции.
Технология измерения производительности
Первый шаг – изменение исходного кода MPI-библиотеки, здесь и далее речь идет именно о MPICH2,
разбирается пример MPI_Bcast, хотя схема работает для любой коллективной операции. В библиотеку
добавляется измененная коллективная операция, с тем же кодом, что и измеряемая, но с одним
дополнительным параметром – номером алгоритма для пересылки.
int MPI_Bcast(void*, int, MPI_Datatype, int, MPI_Comm);
int MPI_Bcast_bnchmrk(void*, int, MPI_Datatype, int, MPI_Comm, int alg);
Далее, создание параллельного приложения выбора лучшего алгоритма. Идея следующая: как и любая
MPI-программа, приложение собирается с библиотекой MPICH2 (уже измененной), и запускается на всем
кластере. Размер MPI_COMM_WORLD в этом случае будет количество доступных узлов.
Далее, в приложении перебираются все возможные размеры коммуникаторов, начиная с 2, и заканчивая
MPI_Comm_size(MPI_COMM_WORLD,…) с единичным шагом. Для каждого размера коммуникатора
перебираются размеры буферов пересылаемых сообщений, начиная с 0 и заканчивая определенным
пользователем значением (как правило, несколько мегабайт) с некоторым промежутком. Реализованы
линейная и логарифмическая шкалы изменения размеров буферов. Теперь, последовательно вызываются все
алгоритмы из имеющихся (в MPICH2 для MPI_Bcast их три) с выбранными размерами коммуникатора и
буфера. Каждый алгоритм вызывается подряд по несколько раз, и измеряется время всех вызовов.
Несколько одних и тех же вызовов делается того, что бы получить усредненное время.
В итоге, для каждого размера коммуникатора и размера буфера получается три (MPICH2, MPI_Bcast)
времени выполнения.
Для каждого размера коммуникатора после перебора всех размеров буферов вычисляются лучшие
алгоритмы, а так же размер буфера, начиная с которого этот алгоритм нужно применять. Например:
0:Btree 200000:Ring 900000:ScGather, т. е., начиная с 0 байт выгоднее использовать
алгоритм «бинарное дерево», с 200 000 байт «кольцевую рассылку», а с 900 000 – «рассылка и сбор».
Такая информация для каждого размера коммуникатора сохраняется в результирующий файл.
В вызов MPI_Init добавляются процедуры чтения сгенерированных файлов и заполнения внутренних
структур данными из этого файла. Вызов MPI_Bcast никак не меняется, однако внутри устроен совсем
иначе – на основе размера коммуникатора и буфера сначала из внутренних данных выбирается номер
лучшего способа передачи, а затем вызывается алгоритм именно с этим номером.
Предложенная схема работает только на гомогенных кластерах по следующей причине: все узлы
кластера имеют одинаковую конфигурацию, и запуск алгоритма, выбранного на этапе измерения, покажет
такую же производительность на некотором подмножестве компьютеров исходной конфигурации. При этом
порядок и количество узлов в файле запуска реального параллельного приложения не будут иметь никакого
значения, т. к. все узлы одинаковы. Здесь же нужно отметить, что узлы должны иметь по одному
процессору, поскольку, очевидно, результаты запуска, например, конфигурации, 2 узла по 2 процесса и 4
узла по одному, даст совершенно разные результаты, т. к. в этом случае латентность пересылок будет играть
самую важную роль.
Можно было бы организовать подобную схему и для кластеров разнородных компьютеров, но придется
изменить алгоритм перебора узлов, а именно, придется для каждого возможного размера коммуникатора
строить перестановки попавших в него узлов и запускать вычисление на каждом таком варианте. Время
работы такой схемы имеет почти факториальное значение от количества узлов кластера. Кроме того, если
бы даже удалось провести такие эксперименты, при запуске приложений пришлось бы анализировать файл
запуска с именами узлов, что тоже не ускорит выполнение параллельной программы.
Так же, нельзя перенести сгенерированные файлы на совершенно другой кластер (с отличной
аппаратной конфигурацией), т. к. измеренные величины корректны только для того суперкомпьютера, на
котором были получены, на других же установках можно получить даже замедление по сравнению со
стандартной схемой, а вовсе не выигрыш.
Тестирование кластеров
Реализованная схема для MPI_Bcast была протестирована на 2-х кластерах: кластер Нижегородского
государственного университета (12 узлов Pentium III 1GHz, 256 Mb RAM, Gigabit Ethernet, OS Win2000AS) и
установка МВС-1000/32, установленная в ИММ УрО РАН (16 узлов 2xPentium 4 2GHz, OS Linux Fedora
Core 1, HyperThreading включён).
Нижегородский кластер показал полное превосходство бинарного дерева, лишь для больших буферов
(более 1-х Мб) лучше оказалась кольцевая рассылка.
МВС-1000/32 показывает наилучшее время для бинарного дерева при данных в среднем менее 800Кб, и
кольцевую рассылку в противном случае. Алгоритм «рассылка-сбор» и на этом кластере лучшим не
оказался ни разу, хотя в стандартной схеме используется часто. Видимо, это связано с очень высокой
латентностью кластера, а «рассылка-сбор» использует много маленьких пересылок, тогда как другие
алгоритмы выполняют по одной пересылке всего буфера целиком.
2
Стандартная схема
1,8
Новая схема
Секунды (20 повторений)
1,6
1,4
1,2
1
0,8
0,6
0,4
0,2
0
1478120
1207722
986340
805088
656691
535193
435720
354278
287599
233006
188310
151716
121755
97225
77142
60699
47237
36215
27191
19802
13753
8801
4746
1426
Буфер (байты)
Рис. 1. Время работы MPI_Bcast на 10 узлах кластера ИММ УрО РАН
Заключение
Реализованная схема определения лучших алгоритмов коллективных операций была протестирована на
двух кластерах, и в результате экспериментов новая схема операции MPI_Bcast показывает выигрыш по
времени до 1,6 раза для большинства вызовов по сравнению со стандартной схемой.
Сейчас ведется подключение других коллективных операций к приложению и MPICH2 и проведение
соответствующих экспериментов. Как видно из результатов для MPI_Bcast, предложенный подход
позволяет во многих случаях существенно сократить время вызовов коллективных операций.
Автор выражает благодарность А. В. Коновалову и А. Г. Пегушину (ЗАО «Интел А/О») за помощь в
разработке, а также ИММ УрО РАН за предоставленные вычислительные ресурсы.
Литература
1.
2.
Thakur R., Gropp W. Improving the Performance of Collective Operations in MPICH. // In proc. of the
EuroPVM/MPI’03, 2003.
Лацис А. О. Как построить и использовать суперкомпьютер. – М.: Бестселлер, 2003. – 274 с.
Related documents
Download