Практические основы параллельного программирования. www.ispras.ru/~posypkin

advertisement
Практические основы
параллельного
программирования.
Посыпкин Михаил Анатольевич
www.ispras.ru/~posypkin
Параллельное
программирование



Приложения требуют увеличения
производительности компьютеров.
Производительность процессора и памяти
ограничена физическими
характеристиками применяемых
материалов.
Многие задачи содержат независимые
компоненты, которые могут решаться
одновременно (т.е. параллельно).
Параллельное
программирование
Перечисленное приводит к естественному
решению – увеличивать число компонент
оборудования, участвующего в решении задач.
В частности, увеличивается число
функциональных устройств одного процессора и
общее число процессоров.
Многопроцессорный
параллелизм
В решении задачи принимает участие несколько
(более одного) процессоров, взаимодействующих
между собой.
CPU
CPU
CPU
CPU
Спектр задач параллельного
программирования

Математическое моделирование:




Оптимизация:



Газовая и гидро-динамика.
Химические реакции.
Процессы в полупроводниках.
Дискретное и линейное программирование.
Общая задача нахождения экстремума.
Оптимальный поиск:



Дискретная оптимизация.
Распознавание образов.
Автоматическая верификация и доказательство
теорем.
Виды параллелизма.
Общая память
Распределенная
память
Аппаратные ресурсы МСЦ

Общая память:



HP V-Class
HP Superdome
Гибридная память:



MVS-1000M (768 x
Alpha 21264)
MVS 15000BM (768
x IBM Power 970)
кластеры Athlon,
Xeon, IBM
Средства параллельного
программирования
Общая память Распределенная
память
Системные
средства
Языки
threads
C/C++,
Fortran 95
Специальные OpenMP
библиотеки и
пакеты
sockets
HPF, DVM, mpC,
Charm ++, Occam
MPI
PVM
Библиотека MPI
Message Passing Interface
Структура MPI


API (варианты для Си, C++, Fortran,
Java).
Средства компиляции и запуска
приложения.
SPMD-модель.
1
2
3
4
Разные процессы
выполняют разные части
одного и того же кода.
Сборка MPI-приложения.
Сборка MPI-приложения осуществляется с помощью
специальной утилиты. В случае Си – mpicc. Пример:
mpicc –o mpihello mpihello.c
Запуск MPI-приложения осуществляется с помощью
команды mpirun.
mpirun –np 4 mpihello
Простейшая MPI-программа
#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( "I am %d of %d\n", rank, size );
MPI_Finalize();
return 0;
}
Функции инициализации и
завершения работы.
int MPI_Init(int* argc,char*** argv)
argc – указатель на счетчик аргументов командной строки
argv – указатель на список аргументов
int MPI_Finalize()
Функции определения ранга
и числа процессов.
int MPI_Comm_size (MPI_Comm comm, int* size )
comm - коммуникатор
size – число процессов
int MPI_Comm_rank(MPI_Comm comm, int* rank)
comm – коммуникатор
rank – ранг процесса
Простейшая пересылка.
#include <mpi.h>
#include <stdio.h>
#define M 3
#define VAL 5
#define ID 1
static int size, rank;
void initArray(int* a, int m, int v)
{
int i;
for(i = 0; i < m; i ++) a[i] = v;
}
void printArray(int* a, int m)
{
int i;
printf("[ ");
for(i = 0; i < m; i ++) printf("%d ", a[i]);
printf("]\n");
}
int main( int argc, char **argv )
{
int dta[M];
MPI_Status status;
MPI_Init( &argc, &argv );
MPI_Comm_size( MPI_COMM_WORLD, &size );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
if( size != 2 ) {
if( rank == 0 ) {
printf("Error: 2 processes required\n");
fflush(stdout);
}
MPI_Abort(MPI_COMM_WORLD, MPI_ERR_OTHER );
}
if( rank == 0 ){
initArray(dta, M, VAL);
MPI_Send(dta, M, MPI_INT, 1, ID, MPI_COMM_WORLD );
printArray(dta, M);
fflush(stdout);
} else {
MPI_Recv(dta, M, MPI_INT, 0, ID, MPI_COMM_WORLD, &status );
printArray(dta, M);
fflush(stdout);
}
}
MPI_Finalize();
return 0;
Функции обменов точкаточка
int MPI_Send( buf, count, datatype, dest, tag, comm )
void *buf;
int count, dest, tag;
MPI_Datatype datatype;
MPI_Comm comm;
/* in */
/* in */
/* in */
/* in */
buf - адрес начала буфера посылаемых данных
count - число пересылаемых объектов типа, соответствующего datatype
dest - номер процесса-приемника
tag - уникальный тэг, идентифицирующий сообщение
datatype - MPI-тип принимаемых данных
comm - коммуникатор
int MPI_Recv( buf, count, datatype, source, tag, comm, status )
void *buf;
int count, source, tag;
MPI_Datatype datatype;
MPI_Comm comm;
MPI_Status *status;
/*
/*
/*
/*
/*
in */
in */
in */
in */
out */
buf - адрес буфера для приема сообщения
count - максимальное число объектов типа datatype, которое
может быть записано в буфер
source - номер процесса, от которого ожидается сообщение
tag - уникальный тэг, идентифицирующий сообщение
datatype - MPI-тип принимаемых данных
comm - коммуникатор
status - статус завершения
typedef struct
{
int count;
int MPI_SOURCE;
int MPI_TAG;
int MPI_ERROR;
} MPI_Status;
count - число полученных элементов
MPI_SOURCE - ранг процесса-передатчика данных
MPI_TAG - тэг сообщения
MPI_ERROR - код ошибки
Download