Е.С.Борисов
четверг, 9 сентября 2004 г.
Существуют задачи, не решаемые на серийных персональных компьютерах за приемлемое время, к примеру прогнозирование погоды, моделирование процессов разрушения в механике (crash-тесты)[1]. Для решения таких задач используют многопроцессорные (параллельные) вычислители. Множество архитектур параллельных вычислителей весьма обширно. Основной характеристикой при классификации [2] параллельных вычислительных систем является способ организации памяти :
Для параллельных вычислительных систем необходимо создавать специальные программы. В тексте такой программы определяются части (ветки), которые могут выполнятся параллельно, а также алгоритм их взаимодействия.
Основным параметром оценки работы параллельной системы является коэффициент ускорения [4] :
(1) |
Эффективность выполнения программы на параллельном вычислителе, в первую очередь, зависит от меры распараллеливания самой задачи, описываемой программой. Параллельные программы, вообще говоря, являются архитектурно зависимыми.
Оценить максимально возможное ускорение для данной программы можно, используя закон Амдала[3] :
Приведем краткое описание технологий параллельных вычислений. Средства параллельных вычислений можно разделить на три уровня :
Выделяют следующие классы параллельных систем.
При написании параллельных программ можно пользоваться коммуникационными библиотеками. Такие библиотеки реализуют методы запуска и управления параллельными процессами, обычно они содержат функции обмена данными между ветвями параллельной программы, функции синхронизации процессов.
Соответственно типу организации памяти, существует два основных типа коммуникационных библиотек [5] и интерфейсов параллельного программирования :
Надо отметить, что одно может быть сымитировано через другое :
Существует множество библиотек и интерфейсов параллельного программирования. Отметим наиболее популярные из них.
Параллельные программы можно писать ''вручную'', непосредственно вставляя в нужные места вызовы коммуникационной библиотеки. Этот путь требует от программиста специальной подготовки. Альтернативой является использование систем автоматического и полуавтоматического распараллеливания последовательных программ.
Дискретная динамическая система (ДДС, transition systems) представляет собой тройку :
Алгебра алгоритмов Глушкова [7] определяется следующим образом. Введем три множества :
Алгеброй алгоритмов назовем пару :
В алгебре алгоритмов (3) определены следующие операции :
где - операторы, - состояние памяти, - условие
где - оператор, - состояние памяти, - условие
В алгебре операторов выделяется множество базовых операторов, а в алгебре условий выделяется множество базовых условий. Таким образом, порождается алгебра алгоритмов .
Регулярное выражение в назовём регулярной программой.
Сформулируем постановку задачи: построить полуавтоматическую систему распараллеливания последовательных программ для параллельных вычислителей с распределенной памятью.
Система полуавтоматического распараллеливания описывается тремя алгебродинамическими моделями :
В основе, представленной ниже, системы полуавтоматического распараллеливания лежат асинхронный вызов подпрограммы и принцип неготового значения[8]. При асинхронном вызове подпрограммы из процесса , выполняющего подпрограмму происходят такие события (рис.2) :
Определим последовательную многокомпонентную программу как упорядоченное множество пар . Каждая такая пара определяет подпрограмму в :
Введем операторы вызова подпрограммы и возврата из подпрограммы .
Процесс выполнения последовательной многокомпонентной программы описывается дискретной динамической системой :
Введем понятие параллельной программы и определим его как упорядоченое множество пар . Каждая такая пара определяет параллельный процесс :
Определим два типа операторов обмена данными между компонентами параллельной программы :
Назовем элементарными операторами все операторы, не являющиеся операторами обмена данными между компонентами параллельной программы.
Процесс выполнения последовательной многокомпонентной программы описывается дискретной динамической системой :
Полуавтоматическая система распараллеливания последовательных программ описывается следующей дискретной динамической системой :
введём обозначения :
Опишем реализацию транслятора-распараллеливателя для языка C.
Вычислительные системы сверхвысокой производительности стоят дорого. Цена таких систем недоступна для большинства образовательных и научно-исследовательских организаций, но часто существует приемлемая альтернатива - кластер. При достаточном числе узлов, такие системы способны обеспечить требуемую производительность.
Можно использовать уже существующую сеть рабочих станций (системы такого типа иногда называют COW - Cluster Of Workstations). При этом узлы могут иметь различную архитектуру, производительность, работать под управлением разных OC (MS Windows, Linux, FreeBSD).
Если узлы планируется использовать только в составе кластера, то их можно существенно облегчить (отказаться от жёстких дисков, видеокарт, мониторов и т.п.). В облегчённом варианте узлы будут загружаться и управляться через сеть. Количество узлов и требуемая пропускная способность сети определяется задачами, которые планируется запускать на кластере.
Message Passing Interface (MPI) - популярный стандарт для построения параллельных программ по модели обмена сообщениями. Этот стандарт обычно используют в параллельных системах с распределённой памятью (кластера и т.п.).
MPI содержит в себе разнообразные функции обмена данными, функции синхронизации параллельных процессов, механизм запуска и завершения параллельной программы. Стандарт MPI-1 описывает статическое распараллеливание, т.е. количество параллельных процессов фиксировано, это ограничение устранено в новом стандарте MPI-2, позволяющем порождать процессы динамически. MPI-2 в настоящее время находится в стадии разработки.
Разными коллективами разработчиков написано несколько программных пакетов, удовлетворяющих спецификации MPI (MPICH, LAM, HPVM etc.). Существуют стандартные ''привязки'' MPI к языкам С, С++, Fortran 77/90, а также реализации почти для всех суперкомпьютерных платформ и сетей рабочих станций.
В данной работе для прогона контрольных примеров был использован кластер на основе сети персональных компьютеров и библиотека MPICH (http://www-unix.mcs.anl.gov/mpi/mpich), созданная авторами спецификации MPI. Этот пакет можно получить и использовать бесплатно. В состав MPICH входит библиотека программирования, загрузчик приложений, утилиты. Существуют реализации этой коммуникационной библиотеки для многих UNIX-платформ, MS Windows.
Для запуска MPI-программ на гомогенном (состоящего из одинаковых узлов, работающих под одной OS) кластере необходимо выполнить следующие шаги.
Для обеспечения более высокого уровня сетевой безопасности можно использовать ssh - OpenSSH remote login client.
Вместо процедуры копирования программы на узлы можно использовать NFS (Network File System) :
После команды mpirun, MPICH, используя rsh, запускает n-раз программу myprog на машинах из machines. При запуске каждому процессу присваивается уникальный номер, и далее программа работает исходя из этого номера.
Используя MPI, можно писать эффективные параллельные программы, но непосредственное программирование в MPI имеет ряд недостатков. MPI можно назвать ассемблером виртуальной многопроцессорной машины. Написание MPI-программ требует от программиста специальной подготовки. Кроме того, MPI-программы, как средство низкого уровня, являются, в значительной мере, архитектурно зависимыми, что затрудняет их переносимость. Описанная система полуавтоматического распараллеливания позволяет решить эти проблемы.
Реализация транслирует программу на расширенном языке C в параллельную MPI-программу на C.
Для того что бы воспользоваться системой полуавтоматического распараллеливания , необходимо выполнить следующие шаги.
asyncron int my_big_func() { /* just do it :) */ return 0; }Вызов такой функций порождает новый параллельный процесс. Таким образом - количество компонент параллельной программы определяется количеством вызовов асинхронных функций.
$ delta myprog.c > myprog_mpi.c components : 4 $ mpicc myprog_mpi.c -o myprog_mpi $ mpirun -machinefile machines -np 4 myprog_mpi
Важной особенностью данной системы является ''гладкий синтаксис''. Введение ключевого слова asyncron является единственным отличием языка C от стандартного C. Программа для распараллеливателя может, без каких либо изменений, собираться обычным (последовательным) транслятором языка C, достаточно добавить в заголовок программы #define asyncron, в этом случае получается обычная (последовательная) программа.
Распараллеливатель можно получить [ здесь ]
Рассмотрим классический пример параллельного программирования - вычисление . Число будем вычислять как определенный интеграл :
Согласно правилу прямоугольников интеграл можно заменить суммой:
$ cc pi.c -o pi $ ./pi pi = 3.1415926535899708
$ delta pi.c > pi_mpi.c components : 3 $ mpicc pi_mpi.c -o pi_mpi $ mpirun -machinefile machines -np 3 pi_mpi pi = 3.1415926535899708
Параллельная MPI-программа вычисления , результат работы распараллеливателя -- [ pi_mpi.c ]