Технология программирования MPI

Preview:

DESCRIPTION

Антонов Александр Сергеевич , к.ф.-м.н., с.н.с. лаборатории Параллельных информационных технологий НИВЦ МГУ. Технология программирования MPI. В операциях коллективного взаимодействия процессов участвуют все процессы коммуникатора ! - PowerPoint PPT Presentation

Citation preview

Технология программирования MPI

Антонов Александр Сергеевич,

к.ф.-м.н., с.н.с. лаборатории Параллельных информационных технологий НИВЦ МГУ

MPI

В операциях коллективного взаимодействия процессов участвуют все процессы коммуникатора!

Как и для блокирующих процедур, возврат означает то, что разрешен свободный доступ к буферу приема или посылки.

Сообщения, вызванные коллективными операциями, не пересекутся с другими сообщениями.

MPIНельзя рассчитывать на синхронизацию процессов с помощью коллективных операций.

Если какой-то процесс завершил свое участие в коллективной операции, то это не означает ни того, что данная операция завершена другими процессами коммуникатора, ни даже того, что она ими начата (если это возможно по смыслу операции).

MPIint MPI_Barrier(MPI_Comm comm)

Работа процессов блокируется до тех пор, пока все оставшиеся процессы коммуникатора comm не выполнят эту процедуру. Все процессы должны вызвать MPI_Barrier, хотя реально исполненные вызовы различными процессами коммуникатора могут быть расположены в разных местах программы.

MPIint MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)

Рассылка сообщения от процесса root всем процессам данного коммуникатора. Значения параметров count, datatype, root и comm должны быть одинаковыми у всех процессов.

MPI

данные

проц

ессы

MPIint MPI_Gather(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int rcount, MPI_Datatype rtype, int root, MPI_Comm comm)

Сборка данных из массивов sbuf со всех процессов в буфере rbuf процесса root. Данные сохраняются в порядке возрастания номеров процессов.

MPIНа процессе root существенными являются значения всех параметров, а на остальных процессах — только значения параметров sbuf, scount, stype, root и comm. Значения параметров root и comm должны быть одинаковыми у всех процессов. Параметр rcount у процесса root обозначает число элементов типа rtype, принимаемых от каждого процесса.

MPI

данные

проц

ессы

MPIint MPI_Gatherv(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int *rcounts, int *displs, MPI_Datatype rtype, int root, MPI_Comm comm)

Сборка различного количества данных из массивов sbuf. Порядок расположения задает массив displs.

MPIrcounts – целочисленный массив, содержащий количество элементов, передаваемых от каждого процесса (индекс равен рангу адресата, длина равна числу процессов в коммуникаторе).

displs – целочисленный массив, содержащий смещения относительно начала массива rbuf (индекс равен рангу адресата, длина равна числу процессов в коммуникаторе).

MPIint MPI_Scatter(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int rcount, MPI_Datatype rtype, int root, MPI_Comm comm)

Рассылка данных из массива sbuf процесса root в массивы rbuf всех процессов. Данные рассылаются в порядке возрастания номеров процессов.

MPI

На процессе root существенными являются значения всех параметров, а на всех остальных процессах — только значения параметров rbuf, rcount, rtype, source и comm. Значения параметров source и comm должны быть одинаковыми у всех процессов.

MPI

данные

проц

ессы

MPIfloat sbuf[SIZE][SIZE], rbuf[SIZE];

if(rank == 0)

for(i=0; i<SIZE; i++)

for (j=0; j<SIZE; j++)

sbuf[i][j]=…;

if (numtasks == SIZE)

MPI_Scatter(sbuf, SIZE, MPI_FLOAT, rbuf, SIZE, MPI_FLOAT, 0, MPI_COMM_WORLD);

MPIint MPI_Scatterv(void *sbuf, int *scounts, int *displs, MPI_Datatype stype, void *rbuf, int rcount, MPI_Datatype rtype, int root, MPI_Comm comm)

Рассылка различного количества данных из массива sbuf. Начало рассылаемых порций задает массив displs.

MPIscounts – целочисленный массив, содержащий количество элементов, передаваемых каждому процессу (индекс равен рангу адресата, длина равна числу процессов в коммуникаторе).

displs – целочисленный массив, содержащий смещения относительно начала массива sbuf (индекс равен рангу адресата, длина равна числу процессов в коммуникаторе).

MPIint MPI_Allgather(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int rcount, MPI_Datatype rtype, MPI_Comm comm)

Сборка данных из массивов sbuf со всех процессов в буфере rbuf каждого процесса. Данные сохраняются в порядке возрастания номеров процессов.

MPI

данные

проц

ессы

MPIint MPI_Allgatherv(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int *rcounts, int *displs, MPI_Datatype rtype, MPI_Comm comm)

Сборка на всех процессах различного количества данных из sbuf. Порядок расположения задает массив displs.

MPIint MPI_Alltoall(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int rcount, MPI_Datatype rtype, MPI_Comm comm)

Рассылка каждым процессом различных данных всем другим процессам. j-й блок данных i-го процесса попадает в i-й блок

j-го процесса.

MPI

данные

проц

ессы

MPIint MPI_Alltoallv(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int rcount, MPI_Datatype rtype, MPI_Comm comm)

Рассылка со всех процессов различного количества данных всем другим процессам.

MPIint MPI_Reduce(void *sbuf, void *rbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)

Выполнение count независимых глобальных операций op над соответствующими элементами массивов sbuf. Результат получается в массиве rbuf процесса root.

MPIТипы предопределенных глобальных операций:

MPI_MAX, MPI_MIN – максимальное и минимальное значения;

MPI_SUM, MPI_PROD – глобальная сумма и глобальное произведение;

MPI_LAND, MPI_LOR, MPI_LXOR – логические “И”, “ИЛИ”, искл. “ИЛИ”;

MPI_BAND, MPI_BOR, MPI_BXOR – побитовые “И”, “ИЛИ”, искл. “ИЛИ”

MPIint MPI_Allreduce(void *sbuf, void *rbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)

Выполнение count независимых глобальных операций op над соответствующими элементами массивов sbuf. Результат получается в массиве rbuf каждого процесса.

MPIfor(i=0; i<n; i++) s[i]=0.0;

for(i=0; i<n; i++)

for(j=0; j<m; j++)

s[i]=s[i]+a[i][j];

MPI_Allreduce(s, r, n, MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD);

MPIint MPI_Reduce_scatter(void *sbuf, void *rbuf, int *rcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)

Выполнение rcounts(i) независимых глобальных операций op над соответствующими элементами массивов sbuf.

i

MPI

Сначала выполняются глобальные операции, затем результат рассылается по процессам.

i-й процесс получает rcounts(i) значений результата и помещает в массив rbuf.

MPIint MPI_Scan(void *sbuf, void *rbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)

Выполнение count независимых частичных глобальных операций op над соответствующими элементами массивов sbuf.

MPI

i-й процесс выполняет глобальную операцию над соответствующими элементами массива sbuf процессов 0…i и помещает результат в массив rbuf.

Окончательный результат глобальной операции получается в массиве rbuf последнего процесса.

MPIint MPI_Op_create (MPI_User_function *func, int commute, MPI_Op *op)

Создание пользовательской глобальной операции. Если commute=1, то операция должна быть коммутативной и ассоциативной. Иначе порядок фиксируется по увеличению номеров процессов.

MPItypedef void MPI_User_function (void *invec, void *inoutvec, int *len, MPI_Datatype type)

Интерфейс пользовательской функции.

int MPI_Op_free(MPI_Op *op)

Уничтожение пользовательской глобальной операции.

MPI

Группа – упорядоченное множество процессов. Каждому процессу в группе сопоставлено целое число – ранг.

MPI_GROUP_EMPTY – пустая группа.

MPI_GROUP_NULL – значение, используемое для ошибочной группы.

Новую группу можно создать только из уже существующих групп или коммуникаторов.

MPI

Коммуникатор – контекст обмена группы. В операциях обмена используются только коммуникаторы!

MPI_COMM_WORLD – коммуникатор для всех процессов приложения.

MPI_COMM_NULL – значение, используемое для ошибочного коммуникатора.

MPI_COMM_SELF – коммуникатор, включающий только вызвавший процесс.

MPIint MPI_Comm_group(MPI_Comm comm, MPI_Group *group)

Получение группы group, соответствующей коммуникатору comm.

MPIint MPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group *newgroup)

Создание группы newgroup из n процессов группы group с рангами ranks(0),…,ranks(n-1), причем рангу ranks(i) в старой группе соответствует ранг i в новой группе. При n=0 создается пустая группа MPI_GROUP_EMPTY.

MPIint MPI_Group_excl(MPI_Group group, int n, int *ranks, MPI_Group *newgroup)

Создание группы newgroup из процессов группы group, исключая процессы с рангами ranks(0),…,ranks(n-1), причем порядок процессов в новой группе соответствует порядку процессов в старой группе.

MPIint MPI_Group_intersection (MPI_Group group1, MPI_Group group2, MPI_Group *newgroup)

Создание группы newgroup из пересечения групп group1 и group2.

MPIint MPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group *newgroup)

Создание группы newgroup из объединения групп group1 и group2.

MPIint MPI_Group_difference (MPI_Group group1, MPI_Group group2, MPI_Group *newgroup)

Создание группы newgroup из разности групп group1 и group2.

MPIint MPI_Group_free(MPI_Group *group)

Уничтожение группы group. Переменная group принимает значение MPI_GROUP_NULL.

MPIint MPI_Group_size(MPI_Group group, int *size)

int MPI_Group_rank(MPI_Group group, int *rank)

Определение количества процессов и номера процесса в группе. Если процесс не входит в группу, то возвращается значение MPI_UNDEFINED.

MPIint MPI_Group_translate_ranks (MPI_Group group1, int n, int *ranks1, MPI_Group group2, int *ranks2)

В массиве ranks2 возвращаются ранги в группе group2 процессов с рангами ranks1 в группе group1.

MPIint MPI_Group_compare(MPI_Group group1, MPI_Group group2, int *result)

Сравнение групп group1 и group2. Если совпадают, то возвращается значение MPI_IDENT. Если отличаются только рангами процессов, то возвращается значение MPI_SIMILAR. Иначе возвращается значение MPI_UNEQAL.

MPIint MPI_Comm_dup(MPI_Comm comm, MPI_Comm *newcomm)

Создание нового коммуникатора newcomm с той же группой процессов и атрибутами, что и у коммуникатора comm.

MPIint MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newcomm)

Создание нового коммуникатора newcomm из коммуникатора comm с группой процессов group. Вызов должен стоять во всех процессах коммуникатора comm. На процессах, не принадлежащих group вернется значение MPI_COMM_NULL.

MPIMPI_Comm_group(MPI_COMM_WORLD, &group);

for(i=0; i<nprocs/2; i++) ranks[i]=i;

if (rank < nprocs/2) MPI_Group_incl(group, nprocs/2, ranks, &new_group);

else MPI_Group_excl(group, nprocs/2, ranks, &new_group);

MPIMPI_Comm_create(MPI_COMM_WORLD, new_group, &new_comm);

MPI_Allreduce(sbuf, rbuf, 1, MPI_INT, MPI_SUM, new_comm);

MPI_Group_rank(new_group, &new_rank);

printf("rank= %d newrank= %d rbuf= %d \n", rank, newrank, rbuf);

MPIint MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)

Разбиение коммуникатора comm на несколько по числу значений параметра color. В одну подгруппу попадают процессы с одним значением color. Процессы с бОльшим значением key получат больший ранг.

MPI

Процессы, которые не должны войти в новые группы, указывают в качестве color константу MPI_UNDEFINED. Им в параметре newcomm вернется значение MPI_COMM_NULL.

MPI_Comm_split(MPI_COMM_WORLD, rank%3, rank, new_comm)

MPIint MPI_Comm_free(MPI_Comm comm)

Удаление коммуникатора comm. Переменной comm присваивается значение MPI_COMM_NULL.

MPIТопология – механизм сопоставления процессам альтернативной схемы адресации. В MPI топологии виртуальны, не связаны с физической топологией сети.

Два типа топологий:

•декартова (прямоугольная решетка произвольной размерности)

•топология графа.

MPIint MPI_Cart_create(MPI_Comm comm, int ndims, int *dims, int *periods, int reorder, MPI_Comm *comm_cart)

Создание декартовой топологии comm_cart. ndims – размерность декартовой решетки, dims – число элементов в каждом измерении.

MPIperiods – массив из ndims элементов, определяющий, является ли решетка периодической вдоль каждого измерения.

reorder – при значении 1 системе разрешено менять порядок нумерации процессов.

Подпрограмма должна быть вызвана всеми процессами коммуникатора.

Некоторым процессам может вернуться значение MPI_COMM_NULL.

MPIint MPI_Dims_create(nnodes, ndims, dims)

Определение размеров dims для каждой из ndims размерностей при создании декартовой топологии для nnodes процессов. dims(i) рассчитывается, если перед вызовом функции оно равно 0, иначе оставляется без изменений.

MPIРазмеры по разным размерностям устанавливаются так, чтобы быть возможно близкими друг к другу. Перед вызовом функции значение nnodes должно быть кратно произведению ненулевых значений массива dims. Выходные значения массива dims, переопределенные функцией, будут упорядочены в порядке убывания.

MPIint MPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int *coords)

Определение декартовых координат процесса по его рангу. Координаты возвращаются в массиве coords. Отсчет координат по каждому измерению начинается с 0.

MPIint MPI_Cart_rank(MPI_Comm comm, int *coords, int *rank)

Определение ранга процесса по его декартовым координатам. Для периодических решеток координаты вне допустимых интервалов пересчитываются, для непериодических – ошибочны.

MPIint MPI_Cart_sub(MPI_Comm comm, int *dims, MPI_Comm *newcomm)

Расщепление коммуникатора comm на подгруппы, соответствующие декартовым подрешеткам меньшей размерности. i–ый элемент массива равен 1, если i–ое измерение должно остаться в подрешетке.

MPIint MPI_Cartdim_get(MPI_Comm comm, int *ndims)

Определение размерности декартовой топологии коммуникатора comm.

MPIint MPI_Cart_get(MPI_Comm comm, int maxdims, int *dims, int *periods, int *coords)

Получение информации о декартовой топологии коммуникатора comm и координатах в ней вызвавшего процесса.

MPIint MPI_Cart_shift(MPI_Comm comm, int direction, int disp, int *source, int *dest)

Получение номеров посылающего (source) и принимающего (dest) процессов в декартовой топологии коммуникатора comm для осуществления сдвига вдоль измерения direction на величину disp.

MPIДля периодических измерений осуществляется циклический сдвиг, для непериодических – линейный сдвиг.

Для n-мерной декартовой решетки значение direction должно быть в пределах от 0 до n-1.

Значения source и dest можно использовать, например, для обмена функцией MPI_Sendrecv.

MPIperiods[0]=1;

periods[1]=1;

MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, 1, &comm);

MPI_Comm_rank(comm, &rank);

MPI_Cart_coords(comm, rank, 2, coords);

MPI_Cart_shift(comm, 0, shift, &source, &dest);

MPI_Sendrecv_replace(a, 1, MPI_FLOAT, dest, 0, source, 0, comm, &status);

MPIint MPI_Graph_create(MPI_Comm comm, int nnodes, int *index, int *edges, int reorder, MPI_Comm *comm_graph)

Создание топологии графа comm_graph. nnodes – число вершин графа, index(i) содержит суммарное количество соседей для первых i вершин.

MPIedges содержит упорядоченный список номеров процессов-соседей.

reorder – при значении 1 системе разрешено менять порядок нумерации процессов.

Подпрограмма должна быть вызвана всеми процессами коммуникатора.

Некоторым процессам может вернуться значение MPI_COMM_NULL.

MPI

nnodes=4

index=2, 3, 4, 6

edges=1, 3, 0, 3, 0, 2

0, 23

32

01

1, 30

СоседиПроцесс

MPIint MPI_Graph_neighbors_count (MPI_Comm comm, int rank, int *nneighbors)

Определение количества непосредственных соседей данной вершины графа.

MPIint MPI_Graph_neighbors(MPI_Comm comm, int rank, int max, int *neighbors)

Определение непосредственных соседей данной вершины графа.

MPIint MPI_Graphdims_get(MPI_Comm comm, int *nnodes, int *nedges)

Определение числа вершин и числа ребер графа.

MPIint MPI_Graph_get(MPI_Comm comm, int maxindex, int maxedges, int *index, int *edges)

Определение информации о топологии графа.

MPIint MPI_Topo_test(MPI_Comm comm,

int *type)

Определение типа топологии, связанной с коммуникатором comm.

• MPI_GRAPH для графа• MPI_CART для декартовой топологии• MPI_UNDEFINED – нет связанной

топологии.

MPI

Сообщение – массив однотипных данных, расположенных в последовательных ячейках памяти.

Для пересылки разнотипных данных можно использовать:

•Производные типы данных

•Упаковку данных

MPI

Производные типы данных создаются во время выполнения программы с помощью подпрограмм-конструкторов.

Создание типа:

•Конструирование типа

•Регистрация типа

MPI

Производный тип данных характеризуется последовательностью базовых типов и набором значений смещения относительно начала буфера обмена.

Смещения могут быть как положительными, так и отрицательными, не требуется их упорядоченность.

MPIint MPI_Type_contiguous(int count, MPI_Datatype type, MPI_Datatype *newtype)

Создание нового типа данных newtype, состоящего из count последовательно расположенных элементов базового типа данных type.

MPIint MPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype type, MPI_Datatype *newtype)

Создание нового типа данных newtype, состоящего из count блоков по blocklen элементов базового типа данных type. Следующий блок начинается через stride элементов после начала предыдущего.

MPIcount=2;

blocklen=3;

stride=5;

MPI_Type_vector(count, blocklen, stride, MPI_DOUBLE, &newtype);

Создание нового типа данных (тип элемента, количество элементов от начала буфера):

{(MPI_DOUBLE, 0), (MPI_DOUBLE, 1), (MPI_DOUBLE, 2),

(MPI_DOUBLE, 5), (MPI_DOUBLE, 6), (MPI_DOUBLE, 7)}

MPIint MPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype type, MPI_Datatype *newtype)

Создание нового типа данных newtype, состоящего из count блоков по blocklen элементов базового типа данных type. Следующий блок начинается через stride байт после начала предыдущего.

MPIint MPI_Type_indexed(int count, int *blocklens, int *displs, MPI_Datatype type, MPI_Datatype *newtype)

Создание нового типа данных newtype, состоящего из count блоков по blocklens(i) элементов базового типа данных. i-й блок начинается через displs(i) элементов с начала буфера.

MPIfor(i=0; i<n; i++){

blocklens[i]=n-i;

displs[i]=(n+1)*i;

}

MPI_Type_indexed(n, blocklens, displs, MPI_DOUBLE, &newtype)

Создание нового типа данных для описания верхнетреугольной матрицы.

MPIint MPI_Type_hindexed(int count, int *blocklens, MPI_Aint *displs, MPI_Datatype type, MPI_Datatype *newtype)

Создание нового типа данных newtype, состоящего из count блоков по blocklens(i) элементов базового типа данных. i-й блок начинается через displs(i) байт с начала буфера.

MPIint MPI_Type_struct(int count, int *blocklens, MPI_Aint *displs, MPI_Datatype *types, MPI_Datatype *newtype)

Создание структурного типа данных из count блоков по blocklens(i) элементов типа types(i). i-й блок начинается через displs(i) байт.

MPIblocklens[0]=3;

blocklens[1]=2;

types[0]=MPI_DOUBLE;

types[1]=MPI_CHAR;

displs[0]=0;

displs[1]=24;

MPI_Type_struct(2, blocklens, displs, types, &newtype);

Создание нового типа данных (тип элемента, количество байт от начала буфера):

{(MPI_DOUBLE, 0), (MPI_DOUBLE, 8), (MPI_DOUBLE, 16),

(MPI_CHAR, 24), (MPI_CHAR, 25)}

MPIint MPI_Type_commit(MPI_Datatype *datatype)

Регистрация созданного производного типа данных datatype. После регистрации этот тип данных можно использовать в операциях обмена.

MPIint MPI_Type_free(MPI_Datatype *datatype)

Аннулирование производного типа данных datatype. datatype устанавливается в значение MPI_DATATYPE_NULL. Производные от datatype типы данных остаются. Предопределенные типы данных не могут быть аннулированы.

MPIint MPI_Type_size(MPI_Datatype datatype, int *size)

Определение размера типа datatype в байтах (объема памяти, занимаемого одним элементом данного типа).

MPIMPI_Type_lb(MPI_Datatype datatype, MPI_Aint *displ)

Определение смещения displ в байтах нижней границы элемента типа данных datatype от базового адреса.

MPIint MPI_Type_ub(MPI_Datatype datatype, MPI_Aint *displ)

Определение смещения displ в байтах верхней границы элемента типа данных datatype от базового адреса.

MPIint MPI_Type_extent(MPI_Datatype datatype, MPI_Aint *extent)

Определение диапазона типа datatype в байтах (разницы между верхней и нижней границами элемента данного типа).

MPIMPI_Address(void *location, MPI_Aint *address)

Определение абсолютного байт-адреса address размещения массива location в оперативной памяти. Адрес отсчитывается от базового адреса, значение которого содержится в константе MPI_BOTTOM.

MPIblocklens[0]=1;

blocklens[1]=1;

types[0]=MPI_DOUBLE;

types[1]=MPI_CHAR;

MPI_Address(dat1, address[0]);

displs[0]=address[0];

MPI_Address(dat2, address[1]);

displs[1]=address[1];

MPI_Type_struct(2, blocklens, displs, types, &newtype);

MPI_Type_commit(newtype);

MPI_Send(MPI_BOTTOM, 1, newtype, dest, tag, MPI_COMM_WORLD);

MPIint MPI_Pack(void *inbuf, int incount, MPI_Datatype datatype, void *outbuf, int outsize, int *position, MPI_Comm comm)

Упаковка incount элементов типа datatype из массива inbuf в массив outbuf со сдвигом position байт. outbuf должен содержать хотя бы outsize байт.

MPI

Параметр position увеличивается на число байт, равное размеру записи. Параметр comm указывает на коммуникатор, в котором в дальнейшем будет пересылаться сообщение.

MPIint MPI_Unpack(void *inbuf, int insize, int *position, void *outbuf, int outcount, MPI_Datatype datatype, MPI_Comm comm)

Распаковка из массива inbuf со сдвигом position байт в массив outbuf outcount элементов типа datatype.

MPIint MPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int *size)

Определение необходимого объема памяти (в байтах) для упаковки incount элементов типа datatype.

MPIfloat a[10];

char b[10], buf[100];

position=0;

if(rank == 0){

MPI_Pack(a, 10, MPI_FLOAT, buf, 100, &position, MPI_COMM_WORLD);

MPI_Pack(b, 10, MPI_CHAR, buf, 100, &position, MPI_COMM_WORLD);

MPI_BCAST(buf, 100, MPI_PACKED, 0, MPI_COMM_WORLD);

}

MPIelse{

MPI_Bcast(buf, 100, MPI_PACKED, 0, MPI_COMM_WORLD);

position=0;

MPI_Unpack(buf, 100, &position, &a, 10, MPI_FLOAT, MPI_COMM_WORLD);

MPI_Unpack(buf, 100, &position, &b, 10, MPI_CHAR, MPI_COMM_WORLD);

}

MPIЗадания:

•написать программу, в которой операция глобального суммирования моделируется схемой сдваивания (каскадная схема) с использованием пересылок данных типа точка-точка. Сравнить эффективность такого моделирования с использованием функции MPI_Reduce.

MPIЗадания:

•написать программу, в которой реализуется распределенное вычисление скалярного произведения двух больших векторов. Исследовать зависимость ускорения программы от числа процессоров для различных длин векторов.

MPI

Литература

1. MPI: A Message-Passing Interface Standard (Version 1.1) (http://parallel.ru/docs/Parallel/mpi1.1/mpi-report.html)

2. Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. СПб.: БХВ-Петербург, 2002.

3. Антонов А.С. Параллельное программирование с использованием технологии MPI: Учебное пособие.-М.: Изд-во МГУ, 2004.

4. Антонов А.С. Введение в параллельные вычисления (методическое пособие). М.: Изд-во Физического факультета МГУ, 2002.

MPI

Литература

5. Букатов А.А., Дацюк В.Н., Жегуло А.И. Программирование многопроцессорных вычислительных систем. Ростов-на-Дону: Издательство ООО "ЦВВР", 2003.

6. Шпаковский Г.И., Серикова Н.В. Программирование для многопроцессорных систем в стандарте MPI: Пособие. Минск: БГУ, 2002.

7. Немнюгин С.А., Стесик О.Л. Параллельное программирование для многопроцессорных вычислительных систем. СПб.: БХВ-Петербург, 2002.

8. Корнеев В.Д. Параллельное программирование в MPI. Новосибирск: Изд-во СО РАН, 2000.

Recommended