Слайд 1 - Сибирский суперкомпьютерный центр

advertisement
MPI за 90 минут
Метод погружения
Сергей Петрович Нечаев,
Сибирский Суперкомпьютерный центр
Параллельное
программирование

«Мы не можем сделать наши
компьютеры быстрее прямо
сейчас, но мы можем
организовать одновременную
работу нескольких
компьютеров над одной
задачей»
Общая и распределенная
память

Средство
коммуникации –
общая память

Коммуникации –
высокоскоростная
сеть

Трудно построить –
легко
программировать

Просто в постройке,
трудно
программировать
Оценки качества параллельной
программы
Она делает то, что нужно
 Работает быстро
 С увеличением числа
процессоров работает быстрее

Ускорение и эффективность
Ускорение: A=T1/Tn
 Эффективность: E=T1/(n*Tn)

Исполнение параллельной
программы

Пакетный режим:
1.
2.
3.
4.
5.
Поставить задачу в очередь
Заняться своими делами
Получить уведомление о
завершении задачи
Вдумчиво проанализировать
результаты
В случае недовольства
пересмотреть программу и
goto 1
Задачи системы очередей
Выделение процессоров для
счета
 Изоляция задач разных
пользователей
 «справедливое» планирование

Запуск параллельной
программы



Компиляция - mpicc test.c –o
program
На ЭВМ с системой очередей Sun
Grid Engine необходимо писать
специальный сценарий и ставить в
очередь не команду mpirun, а этот
сценарий. Пример сценария
#!/bin/bash
#! -V
#$ -cwd mpirun -np $NSLOTS machinefile $TMPDIR/machines
./program
Управление очередью

Постановка задачи в очередь
qsub -pe mpich N < Имя сценария >
 Просмотр
qstat [-f]
состояния очереди
Удаление задачи из очереди
qdel [-f] <номер задачи>
Message passing interface
(MPI)









Инициализация и завершение среды
Идентификация процессов
Парные коммуникации(точка-точка)
Групповые коммуникации
Создание пользовательских типов
данных
Построение пользовательских сетей на
множестве процессоров
Односторонние коммуникации
Порождение новых процессов
Установление соединения между уже
исполняющимися программами
Инициализация и
завершение среды
#include<mpi.h>
int main(int argc, char** argv)
{
….
MPI_Init(&argc, &argv);
//Здесь параллельный код
…..
MPI_Finalize();
return 0;
}
Идентификация Борна
#include <mpi.h>
int main(int argc, char** argv)
{
….
int rank,size;
MPI_Init(&argc, &argv);
//Сколько процессоров
MPI_Comm_size(MPI_COMM_WORLD, &size);
//Кто из них я?
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
…..
MPI_Finalize();
return 0;
}
Hello, parallel world
#include<mpi.h>
#include<stdio.h>
int main(int argc, char** argv)
{
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD,
&rank);
MPI_Comm_size(MPI_COMM_WORLD,
&size);
printf("Hello, MPI world! I am %d
of %d\n",rank,size);
MPI_Finalize();
return 0;
}
Парные коммуникации
У каждого сообщения есть
Отправитель (О) и получатель
(П)
 О должен явно вызвать
функцию отправки, а П –
функцию получения
 Есть блокирующие и не
блокирующие версии

Блокирующие и
неблокирующие функции


Неблокирующие – возвращают
управление немедленно. Для того,
чтобы убедиться, что передача
сообщения прошла и с данными
можно продолжить работу, нужны
дополнительные функции.
Блокирующие –
Возвращение из MPI_Send не
происходит до тех пор, пока
данные сообщения не будут
скопированы во внутренний буфер
MPI. MPI_Recv возвращает
управление только после того, как
сообщение было принято
MPI_Comm_send
int MPI_Send(
void *buffer,//откуда отправляем
int count, //сколько
MPI_Datatype type, //чего
int dest, //куда
int tag, //метка сообщения
MPI_Comm comm //коммуникатор
)
MPI_Comm_recv
int MPI_Recv(
void *buffer,//куда принимаем
int count, //сколько
MPI_Datatype type, //чего
int src, // от кого
int tag, //метка сообщения
MPI_Comm comm, //коммуникатор
MPI_Status *st //хранит полезную
//информацию о том, как прошел прием
)
MPI_ANY_SOURCE – от любого источника
MPI_ANY_TAG – с любой меткой
(только для приема)
Дедлоки

Неформально – ожидание
события, которое никогда не
произойдет
Программа с дедлоком
#include <mpi.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv)
{
int rank,size; char hostname[100];
MPI_Status st;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (size!=2)
{
printf("This example should be run on 2
processors, now exiting\n");
MPI_Finalize();
return 0;
}
else
{
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
gethostname(hostname, 100);
MPI_Send(hostname, 100, MPI_CHAR, !rank, 1,
MPI_COMM_WORLD);
MPI_Recv(hostname, 100, MPI_CHAR, !rank, 1,
MPI_COMM_WORLD,&st);
printf("I am %d of %d. My workmate is %s\n",
rank,size,hostname); MPI_Finalize(); return 0;
}
}
Коллективные коммуникации
Топологии
Коммуникатор
MPI_COMM_WORLD,
создаваемый при запуске
MPI_Init, содержит все
процессы, связанные «каждый
с каждым»
 Есть возможность создавать
свои топологии на любом
подмножестве процессов из
MPI_COWW_WORLD

Типы
Тип – карта памяти
 Существуют
предопределенные константы
для основных типов данных С.
 Есть возможность создавать
пользовательские типы

Порождение процессов
В MPI 1.1 параллельная
программа состоит из заранее
определенного числа
процессов, которое не
меняется в процессе работы
программы
 В MPI 2.0 есть средства для
порождения новых процессов…

Установка соединения
…и установки соединения
между уже исполняющимися
 Функция MPI_Comm_accept,
которая ожидает запроса
соединения от другого процесса –
блокирующаяся.
Неблокирующаяся версия пока
отсутствует в стандарте.

Односторонние
коммуникации

Посредством специального
объекта – окна один MPI
процесс может обратиться к
участку памяти другого MPI
процесса и стянуть/положить
что-нибудь туда
Источники доп. инфо
http://www.mpi-forum.org
 unix man pages
 http://www.ssdonline.sscc.ru/korneev
 http://www.ssd.sscc.ru/nechaev

Это последний слайд
Здесь нужно написать что-то
типа «спасибо за внимание»
или «пожалуйста, вопросы»,
или «удачи в параллельном
мире», а, может быть,
«приходите к нам еще», но я
так и не определился и решил
временно оставить так.
 И за полгода текст этого
слайда не изменился

hpc7000.sscc.ru
 intelnsu
 $IntLab#29
 qsub –pe mvapich script.sh 4
<binary>
 mpiicc --компиляция

Download