Основы параллельного программирования вычислительных систем с распределенной и разделяемой памятью

Автор работы: Пользователь скрыл имя, 05 Июня 2013 в 22:25, курсовая работа

Краткое описание

В настоящее время проводится много исследований в области языков и сред параллельного программирования, целью которых является содействие параллельному программированию путем обеспечения поддержки на должном уровне абстракции. Однако, много эффективных технологий доступно уже сейчас.

Содержание

Введение 4
1 Общие представления о параллельном программировании 6
2 Архитектура параллельных компьютеров 8
2.1 Развитие архитектуры компьютера 8
2.2 Организация памяти параллельных компьютеров 10
2.3 Сети межсоединений 15
2.3.1 Свойства сетей межсоединений. Статические сети межсоединений 16
2.3.2 Динамические сети межсоединений 19
3 Введение в программирование с использованием передачи сообщений 22
3.1 Введение в MPI 22
3.1.1 MPI-коммуникация типа «точка-точка» 25
3.1.2 Тупиковые ситуации при коммуникациях типа «точка-точка» 30
3.1.3 Неблокирующие операции и режимы коммуникации 33
3.1.4 Коммуникационный режим 35
3.2 Групповые коммуникационные операции 36
3.3 Группы процессов и коммуникаторы 41
3.3.1 Группы процессов в MPI 41
3.3.2 Топологии процессов 45
3.3.3 Временные и прерывающие процессы 49
4 Введение в потоковое программирование в OpenMP 50
4.1 Проблемы поточной обработки цикла 52
4.2 Условия гонок 52
4.3 Управление общими и приватными данными 53
4.4 Планирование и разбиение циклов 55
4.5 Библиотечные функции ОреnМР 57
4.6 Отладка 58
4.7 Производительность 59
4.8 Основные моменты 61
5 Протокол сеансового уровня SSH 63
6 Удаленный вход на кластер 66
7 Операционная система Linux 68
7.1 Интерфейс ОС Linux 68
7.2 Некоторые команды Linux 68
8 Компилирование последовательных программ (Fortran/C/C++) 71
9 Основные команды 72
10 Работа с кластером 74
Список использованных источников информации 83

Вложенные файлы: 1 файл

Cluster.doc

— 829.00 Кб (Скачать файл)

MPI_Allgather (sbuf, 100, MPI_INT, rbuf, 100, MPI_INT, comm);

MPI_Allgatherv() является функцией, являющаяся векторным обобщением функции MPI_Allgather() (по аналогии с обобщением функции MPI_Gather()).

Операция мультинакопления (Multi-accumulation Operation)

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

На рисунке 4 показана работа операции мультинакопления.

Рисунок 4 – Операция мультинакопления

Каждый процесс аккумулирует один и тот же блок данных. Соответствующая  данной операции MPI-функция имеет вид:

int MPI_Allreduce (void *sendbuf,

    void *recvbuf,

    int count,

    MPI_Datatype type,

    MPI_Op op,

    MPI_Comm comm)

Общий обмен (Total Exchange)

Для осуществления общего обмена в MPI имеется функция

int MPI_Alltoall (void *sendbuf,

  int sendcount,

  MPI_Datatype sendtype,

  void *recvbuf,

  int recvcount,

  MPI_Datatype recvtype,

  MPI_Comm comm)

Здесь sendbuf – буфер передачи, в который каждый процесс сохраняет блок данных типа sendtype, состоящий из sendcount элементов и предназначаемый для всех процессов (включая себя). Блоки данных, получаемые от других процессов, сохраняются в буфер приема recvbuf. Полученные блоки сохраняются в порядке рангов передающих процессов. Для p процессов результат общего обмена также может быть достигнут, если каждый из p процессов выполнит p операций передачи

MPI_Send (sendbuf+i*sendcount*extent, sendcount, sendtype,i, my_rank, comm)

и p операций приема

MPI_Recv (recvbuf+i*recvcount*extent, recvcount, recvtype,

    i, i, comm, &status),

где i – ранг процесса, .

MPI_Alltoallv() – векторная версия функции MPI_Alltoall().

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

3.3 Группы процессов и коммуникаторы

MPI позволяет строить подмножества процессов путем определения групп и коммуникаторов и осуществлять над ними различные операции (например, объединение или пересечение групп, сравнение групп). Эти операции позволяют строить сложные коммуникационные области, способствующие параллельным процессам эффективно обмениваться данными. Также в MPI имеются средства задания различных виртуальных топологий, обеспечивающие удобный механизм наименования процессов, связанных коммуникатором и являющиеся мощным средством отображения процессов на оборудование системы.

Группа процессов – упорядоченное множество процессов прикладной программы. Каждый процесс группы получает уникальный номер, также называемый рангом. Ранги процессов группы всегда начинаются с нуля и далее последовательно увеличиваются вплоть до числа процессов минус один. Процесс может быть членом нескольких групп, и ранг этого процесса в различных группах может отличаться. Для программиста группа процессов – объект типа MPI_Group, доступ к которому может быть получен с использованием дескриптора, который может быть индексом или ссылкой.

3.3.1 Группы процессов в MPI

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

int MPI_Comm_group (MPI_Comm comm, MPI_Group *group)

где comm – данный коммуникатор, можно получить указатель group на ранее определенный объект типа MPI_Group. Предопределенной является группа MPI_GROUP_EMPTY, обозначающая пустую группу процессов.

 Рассмотрим операции над группами процессов.

Объединение существующих групп group1 и group2

int MPI_Group_union (MPI_Group group1,

          MPI_Group group2,

          MPI_Group *new_group)

Ранги в новой группе new_group устанавливаются так, что процессы группы group1 сохраняют свои ранги. Процессы группы group2, не находящиеся в группе group1, получают ранги, начиная с ранга последнего процесса группы group1 плюс один.

Пересечение двух групп

int MPI_Group_intersection (MPI_Group group1,

             MPI_Group group2,

             MPI_Group *new_group)

Процессы в группе new_group получают последовательные ранги, начиная с нуля.

Разность множеств двух групп

int MPI_Group_difference (MPI_Group group1,

            MPI_Group group2,

            MPI_Group *new_group)

Подгруппа new_group существующей группы group может быть получена путем вызова функции

int MPI_Group_incl (MPI_Group group,

int p,

int *ranks,

MPI_Group *new_group)

Здесь ranks – целочисленный массив, состоящий из p элементов. Ранги процессов группы-результата – от 0 до p-1.

Из данной группы можно  удалить процессы путем вызова функции

int MPI_Group_excl (MPI_Group group,

int p,

int *ranks,

MPI_Group *new_group)

Этот вызов генерирует новую группу new_group, полученную из группы group путем удаления процессов с рангами ranks[0],…,ranks[p-1].

Доступ к структурам данных типа MPI_Group не может быть напрямую получен программистом. Но MPI предоставляет операции, позволяющие получить информацию о группах процессов. Размер size группы процессов можно узнать путем вызова функции

int MPI_Group_size (MPI_Group group, int *size)

Ранг rank вызывающего процесса группы может быть получен с помощью функции

int MPI_Group_rank (MPI_Group group, int *rank)

Функция

int MPI_Group_compare (MPI_Group group1, MPI_Group group2,     int *res)

может быть использована для  того, чтобы проверить, описывают  ли два представления группы group1 и group2 одну и ту же группу. Если обе эти группы содержат одни и те же процессы в одном и том же порядке, то возвращается параметр res = MPI_IDENT. res = MPI_SIMILAR возвращается в случае, если обе группы содержат одни и те же процессы, но порядок процессов в группах отличается. res = MPI_UNEQUAL означает, что группы содержат различные процессы.

Функция

int MPI_Group_free (MPI_Group *group)

может быть использована с  целью удаления группы. Дескриптор группы после этого установится  в MPI_GROUP_NULL.

Рассмотрим операции над коммуникаторами.

В MPI имеется два типа коммуникаторов:

  • интракоммуникатор (intra-communicator) используется для связи и для групповых операций внутри отдельной группы процессов;
  • интеркоммуникатор (inter-communicator) используется для точечной связи между двумя непересекающимися группами процессов.

Новый интракоммуникатор  данной группы процессов может быть сгенерирован путем вызова функции

int MPI_Comm_create (MPI_Comm comm,

MPI_Group group,

MPI_Comm *new_comm)

где comm определяет существующий коммуникатор. Параметр group должен определять группу процессов, являющуюся подмножеством группы процессов, ассоциированной с comm. Для корректного исполнения необходимо, чтобы все процессы коммуникатора comm вызывали MPI_Comm_create(), и чтобы все эти процессы имели одинаковые параметры group. В результате вызова функции каждый вызывающий процесс-член группы group получает в параметре new_comm указатель на новый коммуникатор.

MPI также предоставляет функции, позволяющие получить информацию о коммуникаторах. Размер size группы процессов, ассоциированной с коммуникатором comm, можно узнать путем вызова функции

int MPI_Comm_size (MPI_Comm comm, int *size)

Ранг rank процесса-члена группы, связанной с коммуникатором comm может быть получен путем вызова функции

int MPI_Comm_rank (MPI_Comm comm, int *rank)

 Два коммуникатора можно сравнить:

int MPI_Comm_compare (MPI_Comm comm1, MPI_Comm comm2, int *res)

Результат сравнения возвращается в параметре res:

  • res = MPI_IDENT – коммуникаторы представляют одну и ту же  структуру данных;
  • res = MPI_CONGRUENT – группы, связанные с коммуникаторами, содержат одни и те же процессы в одном и том же порядке;
  • res = MPI_SIMILAR – группы содержат одни и те же процессы, но порядок разный;
  • res = MPI_UNEQUAL – группы содержат различные процессы.

Для конструирования коммуникаторов MPI предоставляет операции копирования, удаления и разделения коммуникаторов на части:

int MPI_Comm_dup (MPI_Comm comm, MPI_Comm *new comm)

 

int MPI_Comm_free (MPI_Comm *comm)

 

int MPI_Comm_split ( MPI_Comm comm,

int color,

int key,

MPI_Comm *new_comm)

Результатом последней функции  является разделение группы процессов, ассоциированной с коммутатором comm, на непересекающиеся подгруппы. Количество подгрупп определяется числом различных значений параметра color. Каждая подгруппа содержит все процессы с одинаковым значением color. В пределах каждой подгруппы процессы ранжируются в порядке, определенном параметром key. Если два процесса в подгруппе определяют одинаковые значения key, то используется порядок, имевший место в исходной группе. Если процесс коммуникатора comm определяет color = MPI_UNDEFINED, то он не станет членом ни одной из создаваемых групп. Каждый процесс коммуникатора comm получает указатель new_comm на коммуникатор подгруппы, содержащей процесс. Если определено color = MPI_UNDEFINED, то в качестве new_comm будет возвращено MPI_COMM_NULL.

3.3.2 Топологии процессов

Каждый процесс из некоторой группы процессов имеет уникальный ранг в пределах этой группы, который может быть использован для коммуникации с данным процессом. Однако часто полезно иметь альтернативное представление процесса и доступ к нему; это полезно тогда, когда алгоритм выполняет вычисления над двух- или трехмерной решеткой, узлы которой назначены  различным процессам, и процессы обмениваются данными с соседними процессами в каждом измерении путем коммуникаций. MPI поддерживает логическое распределение процессов путем определения виртуальных топологий для интракоммуникаторов.

Виртуальная декартова структура  решетки для произвольного измерения  может быть сгенерирована путем  вызова функции

int MPI_Cart_create (MPI_Comm comm,

int ndims,

int *dims,

int *periods,

int reorder,

MPI_Comm *new_comm)

Здесь comm – исходный коммутатор безо всякой топологии, ndims определяет количество измерений генерируемой решетки, dims – целочисленный массив размера ndims такой, что dims[i] – число процессов в измерении i. Логический массив periods размера ndims для каждого измерения определяет, является в данном измерении ли решетка периодической (1 или true) или нет (0 или false). Значение reorder = false соответствует тому, что процессы в новом коммуникаторе new_comm будут иметь такие же ранги, как и в коммуникаторе comm. Если reorder = true, то исполняющей системе разрешается изменить порядок процессов, например, с тем, чтобы достичь лучшего отображения топологии процессов на физическую сеть параллельной машины.

Пример. Рассмотрим коммуникатор с 12 процессами. Пусть ndims=2, dims[0]=3, dims[1]=4, periods[0]=periods[1]=0, reorder=0, тогда вызов

MPI_Cart_create (comm, ndims, dims, periods, reorder, &new_comm)

сгенерирует виртуальную  решетку 3x4 со следующими рангами групп и координатами:

 

0

(0,0)

1

(0,1)

2

(0,2)

3

(0,3)

4

(1,0)

5

(1,1)

6

(1,2)

7

(1,3)

8

(2,0)

9

(2,1)

10

(2,2)

11

(2,3)


Декартовы координаты представлены в форме (строка, столбец). #

Чтобы помочь программисту выбрать  сбалансированное распределение процессов для различных измерений, MPI предоставляет функцию

int MPI_Dims_create (int nnodes, int ndims, int *dims)

где ndims – число измерений решетки, nnodes – общее количество доступных процессов. Параметр dims – целочисленный массив размера ndims. Размерности устанавливаются так, чтобы быть близко друг к другу насколько возможно, используя соответствующий алгоритм делимости. Пользователь может ограничивать действие этой функции, определяя элементы массива dims. Если в dims[i] уже записано число, то функция не будет изменять количество узлов в измерении i; функция модифицирует только нулевые элементы  массиве, т.е. где dims[i]=0.

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

Информация о работе Основы параллельного программирования вычислительных систем с распределенной и разделяемой памятью