Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
MPI - MKM.docx
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
391.79 Кб
Скачать

2. Виртуальные топологии. Декартова и графовая топологии. В каких случаях их следует использовать. Основные шаги для создания декартовой топологии.

В MPI топология представляет собой механизм для того, чтобы связать с процессами, принадлежащими группе, различные схемы адресации. Топология MPI - виртуальная, т. е. может не существовать никакого простого отношения между структурой процессов, определенной виртуальной топологией и фактической физической структурой параллельной машины. Известны два основных типа виртуальной топологии, которая может быть создана MPI, - декартова топология, или топология сетки, и топология графа. Первый тип является подмножеством второго. В дек. топ. множ-во процессов предст-ся в виде прям. решетки, а для указ. процессов исп-ся дек. сист. коорд. Для созд-я :int MPI_Cart_create(MPI_Comm oldcomm, int ndims, int *dims, int *periods, int reorder, MPI_Comm *cartcomm), где: oldcomm - исх. комм; ndims - разм. дек. решетки, dims - массив длины ndims, задает кол-во процессов каждом изм. решетки, periods - массив длины ndims, определяет, явл-ся ли решетка периодич. вдоль каждого изм; reorder - параметр допустимости изм. нум. процессов, cartcomm – созд-е. комм. с дек. топ. процесса. В топологии в виде графа - вершины есть процессы системы, а дуги соответствуют имеющимся каналам связи. Парные операции передачи данных могут быть выполнены между любыми процессами комм; в коллект. операции приним. участие все процессы комм. Следовательно, логическая топ. линий связи между процессами в парал. программе имеет структуру полного графа.

3. Параллельное умножение матрицы и вектора в mpi.

intsize,rank;

MPI_Status status;

MPI_Init(&argc,&argv);

MPI_Comm_rank(MPI_COMM_WORLD,&rank);

MPI_Comm_size(MPI_COMM_WORLD,&size);

inti,k,j,s,x=0,p;

int n=10, a[n][n], c[n], b[n], d[p];

p=n/(size-1);

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

{

b[i]=i; for(j=0;j<n;j++) { a[i][j]=x;x++; }

}

if (rank!=size-1)

{ for(k=rank*p;k<p*(rank+1);k++) {

s=0; for(int j=0;j<n;j++)

{ s+=a[k][j]*b[j]; } d[k]=s; }

MPI_Send(&d[rank*p],p,MPI_DOUBLE,size-1,5,MPI_COMM_WORLD);

}

else

{ for (i=0; i<size-1;i++) { MPI_Recv(&c[i*p],p,MPI_DOUBLE,i,5,MPI_COMM_WORLD, &status); } }

53 Сурак

7 Состояние гонки. Алгоритм с конкуренцией. Синхронизация. Задача обедающих философов.

Состояние гонки — это ошибка, возникающая, когда результат программы зависит от того, какой из двух (или более) потоков первым достигнет определенного блока кода. При многократном запуске программы получаются разные непредсказуемые результаты.

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

Задача обедающих философов.

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

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

Нетрудно заметить, что в данной задаче философы представляют собой потоки, а вилки – общие разделяемые ресурсы. Тогда первое очевидное, на первый взгляд, решение состоит в том, чтобы для каждой вилки (ресурса) ввести отдельный семафор для блокировки философа (потока) в ситуации, когда нужная для еды вилка уже занята соседним философом. Кроме того, можно применить некоторое регламентирующее правило порядка взятия вилок – например, философ сначала берет левую вилку, затем правую. Итак, получаемый в результате алгоритм деятельности каждого философа состоит в следующем: как только философ приступает к еде, он пытается взять левую вилку. Если она занята, философ ждет ее освобождения и в конце концов ее получает. Затем философ пытается взять правую вилку. И опять же, если вилка занята, философ снова ждет ее освобождения (при этом левую вилку он по-прежнему хранит у себя). После получения правой вилки философ ест спагетти, после чего освобождает обе вилки. Возможная реализация предложенной схемы (опять же с использованием семафоров) может состоять в следующем.

// Семафоры доступа к вилкам

Semaphore fork[5] = { 1, 1, 1, 1, 1 };

// Поток -философ (для всех философов одинаковый)

Prilosopher(){

// i – номер философа

while (1) { P(fork[i]); // Доступ к левой вилке P(fork[(i+1)%5]); // Доступ к правой вилке <Питание>

// Освобождение вилок

V(fork[i]); V(fork[(i+1)%5])

<Размышление> } }

(выражение (i+1)%5 определяет номер правой вилки, % есть операция получения остатка от целого деления в алгоритмическом языке С).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]