30135

ИЗУЧЕНИЕ МОДЕЛЕЙ ВЗАИМОДЕЙСТВИЯ РАСПРЕДЕЛЕННО ВЫПОЛНЯЮЩИХСЯ ПРОЦЕССОВ

Лабораторная работа

Информатика, кибернетика и программирование

Осуществить построение топологии сети требуемого вида (рис. 3.1); выполнить широковещательную рассылку вводимого с клавиатуры сообщения от узла S на все остальные узлы. На узле, инициирующем рассылку, выводить (в виде матрицы) топологию сети и остовное дерево, на остальных хостах сети после получения сообщения выводить номер хоста и сам текст сообщения.

Русский

2013-08-23

65.72 KB

6 чел.

Министерство образования, науки, молодежи и спорта Украины

Севастопольский национальный технический университет

Лабораторная работа №5

ИЗУЧЕНИЕ МОДЕЛЕЙ ВЗАИМОДЕЙСТВИЯ РАСПРЕДЕЛЕННО ВЫПОЛНЯЮЩИХСЯ ПРОЦЕССОВ

Выполнил:

Ст. гр. И-32д

Сычев П.Ю

Проверил:

Кротов К.В

Севастополь

2012

Цель работы:

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

Вариант 1

Осуществить построение топологии сети требуемого вида (рис. 3.1); выполнить широковещательную рассылку вводимого с клавиатуры сообщения от узла S на все остальные узлы. На узле, инициирующем рассылку, выводить (в виде матрицы) топологию сети и остовное дерево, на остальных хостах сети после получения сообщения выводить номер хоста и сам текст сообщения.

Текст программы:

// lab5.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include "mpi.h"

#include "conio.h"

#include "iostream"

using namespace std;

int main(int argc, char **argv)

{

int rank;

   MPI_Status status;

 MPI_Comm new_comm;

//массив, описывающий степени узлов

int index[]={2,5,7,10,12};

//массив, описывающий ребра графа

 int edges[]={1,3,0,2,4,1,3,0,2,4,1,3};

int message[300];

int* temp;

temp=new int[300];

 

   MPI_Init(&argc, &argv);

   MPI_Comm_rank(MPI_COMM_WORLD, &rank);

//создание топологии графа

MPI_Graph_create(MPI_COMM_WORLD,5,index,edges,false,&new_comm);

 int count;

//узнаем количество соседей процесса в топологии

 MPI_Graph_neighbors_count(new_comm,rank,&count);

int* nei=new int[count];

 //получаем список соседей процесса в топологии

 MPI_Graph_neighbors(new_comm,rank,count,nei);

MPI_Comm_rank(new_comm, &rank);

 int first;

/*

Все процессы кроме первого начинают свою работу

с того, что ожидают зонда

*/

 if (rank)

{

 //ожидание зонда

 MPI_Recv(message,300,MPI_INT,MPI_ANY_SOURCE,99,new_comm,&status);

 cout<<"Process "<<rank<<"\t Recv zond from process "<<message[1]<<endl;

 /*

 Запоминаем тот процесс, который первым прислал нам зонд.

 Ему нужно будет вернуть эхо

 */

 if (message[0]==1)

  first=message[1];

}

/*

message[0] - тип сообщения

     =1 - зонд

     =2 - эхо

message[1] - ID источника соообщение

*/

message[0]=1;

message[1]=rank;

//каждый процесс рассылает всем своим соседям зонды

 for (int i=0;i<count;i++)

{

 cout<<"Process "<<rank<<"\t Send zond to process "<<nei[i]<<endl;

 MPI_Send(message,300,MPI_INT,nei[i],99,new_comm);

}

int from;

int all=count*2;

if (rank)

 all--;

for (int i=0;i<300;i++)

 temp[i]=0;

/*

В матрице temp(и message), которая будет передаваться в сообщении,

в элементах с индексами от 2 до 2+25 будет храниться последовательность

строк двумерной матрицы связности кластера.

Т.е. temp[i][j]=1, если есть ребро соединяющее вершины i и j

Иначе элемент равен 0

*/

//Записываем строку матрицы топологии для процесса rank

 for (int i=0;i<count;i++)

{

 temp[ rank*5 + nei[i] + 2 ]=1;

 temp[ nei[i]*5 + rank + 2]=1;

}

for (int i=0;i<all;i++)

{

 MPI_Recv(message,300,MPI_INT,MPI_ANY_SOURCE,99,new_comm,&status);

 cout<<"Process "<<rank<<"\t Recv message from process "<<message[1];

 if (message[0]==1)

  cout<<"\t It is zond ";

 else

  cout<<"\t It is echo ";

 cout<<endl;

 //зонд

 if (message[0]==1)

 {

  //узнаем, от окго пришло сообщение

  from=message[1];

  message[0]=2;

  message[1]=rank;

  //message[99]==-1 - признак пустого эха

  message[99]=-1;

  cout<<"Process "<<rank<<"\t Send empty echo to process "<<from<<endl;

  MPI_Send(message,300,MPI_INT,from,99,new_comm);

 }

 //эхо

 else if (message[0]==2)

 {

  //не пустое

  if (message[99]!=-1)

  {

   //добавляем полученную часть топологии

   for (int i=2;i<300;i++)

    if (message[i]==1)

     temp[i]=1;

  }

 }

}

if (rank)

{

 cout<<"Process "<<rank<<"\t Send final echo to process "<<first<<endl;

 temp[99]=1;

 temp[0]=2;

 temp[1]=rank;

 MPI_Send(temp,300,MPI_INT,first,99,new_comm);

}

if (!rank)

{

 cout<<endl<<"Topologiya klastera"<<endl;

 for (int i=0;i<5;i++)

 {

  for (int j=0;j<5;j++)

  {

   cout<<temp[5*i + j + 2]<<"\t";

  }

  cout<<endl;

 }

 cout<<endl;

}

int ostov[5][5];

for (int i=0;i<5;i++)

 for (int j=0;j<5;j++)

  ostov[i][j]=0;

/*

Получаем из топологии остов дерева

На каждом шаге алгоритма добавляем по одному ребру

т.о., чтобы одна вершина ребра была среди уже добавленных,

а вторая - нет. Эту, вторую вершину, добавляем в список добавленных.

Вершина на первом шаге добавляется произвольно

 */

if (!rank)

{

 bool used[5];

 for (int i=0;i<5;i++)

  used[i]=false;

 used[0]=true;

 for (int i=0;i<4;i++)

 {

  bool done=false;

  for (int j=0;j<5;j++)

  {

   if (used[j])

   {

    for (int k=0;k<5;k++)

     if ((!used[k])&&(temp[5*j + k + 2]))

     {

      ostov[j][k]=1;

      ostov[k][j]=1;

      done=true;

      used[k]=true;

      break;

     }      

   }   

   if (done)

    break;

  }

 }

 cout<<endl<<"Ostovnoe derevo"<<endl;

 for (int i=0;i<5;i++)

 {

  for (int j=0;j<5;j++)

  {

   cout<<ostov[i][j]<<"\t";

  }

  cout<<endl;

 }

 cout<<endl<<"Enter the message "<<endl;

 }

char s[250];

/*

Считываем строку

Сообщение будем передавать в массиве temp

temp[0] - длина строки

далее идет temp[0] элементов массива temp, определяющих строку

каждый элемент - очередная буква строки

после строки 25 элементов матрицы temp - остовное дерево

 */

if (!rank)

{

 scanf("%s",s);

 temp[0]=strlen(s);

 for (int i=0;i<temp[0];i++)

 {

  temp[i+1]=(int)s[i];

 }

 for (int i=0;i<5;i++)

  for (int j=0;j<5;j++)

   temp[temp[0] + 1 + 5*i + j]=ostov[i][j];

 }

/*

Все процессы кроме первого принимают одно сообщение

 */

if (rank)

{

 MPI_Recv(temp,300,MPI_INT,MPI_ANY_SOURCE,99,new_comm,&status);

 for (int i=0;i<temp[0];i++)

  s[i]=(char)temp[i+1];

 s[temp[0]]='\0';

 cout<<"Process "<<rank<<"\t Message "<<s<<endl;

 }

/*

Весь столбец остовной матрицы, соотв. процессу rank, обнуляется

Для того, чтобы снова не отсылать ему сообщение, которое он сам разослал

*/

for (int i=0;i<5;i++)

{

 temp[temp[0] + 1 + 5*i + rank]=0;

}

/*

Отсылаем сообщения каждому соседу, только если не получили от

него сообщение сами

*/

for (int i=0;i<5;i++)

 if (temp[temp[0] + 1 + 5*rank + i]==1)

  MPI_Send(temp,300,MPI_INT,i,99,new_comm);

 MPI_Finalize();

return 0;

}

Вывод:

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


 

А также другие работы, которые могут Вас заинтересовать

72471. ПОНЯТИЕ О НЕОТЛОЖНЫХ СОСТОЯНИЯХ. ПРИЧИНЫ И ФАКТОРЫ ИХ ВЫЗЫВАЮЩИЕ И ПЕРВАЯ ДОВРАЧЕБНАЯ ПОМОЩЬ 63.5 KB
  В жизни каждого человека вследствие различных причин могут произойти случаи когда его соматическое и физическое здоровье резко меняется ему становится плохо он может даже потерять сознание. При таком состоянии человеку требуется срочная помощь.
72472. Восточные славяне в древности 89 KB
  Славянские народы принадлежат к древнему индоевропейскому единству, включающему такие народы как германские, балтийские, романские, греческие, кельтские, иранские, индийские раскинувшиеся на огромном пространстве от Атлантического океана до Индийского, от Ледовитого океана до Средиземного моря.
72473. ВОЛНОВЫЕ МЕХАНИЧЕСКИЕ ПЕРЕДАЧИ 609 KB
  Генератор устроен так чтобы деформированное гибкое колесо прижималось к внутренней цилиндрической поверхности жесткого колеса с силой достаточной для передачи нагрузки за счет сил трения. При вращении генератора волна перемещений бежит по окружности гибкого колеса.
72474. Подшипники. Назначение и классификация 473.5 KB
  Подшипники служат опорами для валов и вращающихся осей. Они воспринимают радиальные и осевые нагрузки, приложенные к валу, и передают их на раму машины. При этом вал должен фиксироваться в определенном положении и вращаться вокруг заданной геометрической оси.
72475. ПОДШИПНИКИ КАЧЕНИЯ. ОБЩИЕ СВЕДЕНИЯ И КЛАССИФИКАЦИЯ 975.5 KB
  Применение подшипников качения позволило заменить трение скольжения трением качения. Конструкция подшипников качения позволяет изготовлять их в массовых количествах как стандартную продукцию что значительно снижает стоимость производства.
72476. ЧЕРВЯЧНЫЕ ПЕРЕДАЧИ 380 KB
  Существенное отличие червячной передачи от зубчатой заключается в том, что окружные скорости червяка и колеса не совпадают как по величине, так и по направлению. Они направлены друг к другу под углом перекрещивания.
72477. ОСОБЕННОСТИ РАСЧЕТА ПЛАНЕТАРНЫХ ПЕРЕДАЧ 307.5 KB
  Планетарными называют передачи, включающие в себя зубчатые колеса с перемещающимися осями (рис.10.1,а). Передача состоит из центрального колеса с наружными зубьями, центрального колеса b с внутренними зубьями и водила Н, но котором укреплены оси сателлитов g.
72478. ПЕРЕДАТОЧНОЕ ОТНОШЕНИЕ ОДНОСТУПЕНЧАТЫХ И МНОГОСТУПЕНЧАТЫХ ЗУБЧАТЫХ ПЕРЕДАЧ 181 KB
  Масса и габариты редуктора в значительной степени зависят от того, как распределено общее передаточное отношение по ступеням передачи. Лучшие показатели имеют редукторы, у которых диаметры колес (а не шестерен) всех ступеней близки между собой.
72479. МЕХАНИЧЕСКИЕ ПЕРЕДАЧИ 785.5 KB
  Передача состоит из двух шкивов закрепленных на валах и ремня охватывающего шкивы. В зависимости от формы поперечного сечения ремня различают: плоскоременную рис. Основные преимущества ременной передачи: возможность передачи движения на значительное расстояние до 15 м и более...