Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лабы по ВС 1-09 -2011г.doc
Скачиваний:
6
Добавлен:
14.11.2019
Размер:
1.29 Mб
Скачать

Определения структуры приходящего сообщения

Иллюстрация применения процедуры MPI_Probe ДЛЯ определения структуры приходящего сообщения. Процесс 0 ждет сообщения от любого из процессов 1 и 2 с одним и тем же тегом. Однако посылаемые этими процессами данные имеют разный тип. Для того чтобы определить, в какую переменную помещать приходящее сообщение, процесс сначала при помощи вызова MPI_Probe определяет, от кого же именно поступило это сообщение. Следующий непосредственно после MPI_Probe вызов MPI_Recv гарантированно примет нужное сообщение, после чего принимается сообщение от другого процесса.

Пример 8:

#include <stdio.h>

#include "mpi.h"

void main(int argc,char * argv[])

{

int rank,ierr,ibuf;

struct MPI_Status status;

float rbuf;

ierr=MPI_Init(&argc,&argv);

ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);

ibuf=rank;

rbuf=1.0F*rank;

switch (rank)

{

case 1:

{

ierr=MPI_Send(&ibuf,1,MPI_INT,0,5,MPI_COMM_WORLD);

break;

}

case 2:

{

ierr=MPI_Send(&rbuf,1,MPI_FLOAT,0,5,MPI_COMM_WORLD); break;

}

case 0:

{

ierr=MPI_Probe(MPI_ANY_SOURCE,5,MPI_COMM_WORLD,&status);

if (status.MPI_SOURCE==1)

// message from process 1 received first

{ ierr=MPI_Recv(&ibuf,1,MPI_INT,1,5, MPI_COMM_WORLD,&status);

ierr=MPI_Recv(&rbuf,1,MPI_FLOAT,2,5, MPI_COMM_WORLD,&status);

} else // message from process 2 received first

if (status.MPI_SOURCE==2) // ignore messages from other processes

{ ierr=MPI_Recv(&rbuf,1,MPI_FLOAT, 2,5,MPI_COMM_WORLD,&status);

ierr=MPI_Recv(&ibuf,1,MPI_INT, 1,5,MPI_COMM_WORLD,&status);}

printf("Process 0 recv %i from process 1 %1f from process 2\n",ibuf,rbuf);

break;

}

}

ierr=MPI_Finalize();

}

Задание: Добавьте в программу процесс 3, передающий в качестве сообщения процессу 0 ваше имя.

Определение базовых характеристик коммуникационной сети

Приведена программа, в которой моделируется последовательный обмен сообщениями между двумя процессами, замеряется время на одну итерацию обмена, определяется зависимость времени обмена от длины сообщения. Таким образом, определяются базовые характеристики коммуникационной сети параллельного компьютера: латентность (время на передачу сообщения нулевой длины) и максимально достижимая пропускная способность (количество мегабайт в секунду) коммуникационной сети, а также длина сообщений, на которой она достигается. Константа NMАХ задает ограничение на максимальную длину посылаемого сообщения, а константа NTIMES определяет количество повторений для усреднения результата. Сначала посылается сообщение нулевой длины для определения латентности, затем длина сообщений удваивается, начиная с посылки одного элемента типа float[8].

Пример 9:

#include <stdio.h>

#include "mpi.h"

int main(int argc,char * argv[])

{

int ierr,rank,size,i,n,nmax,lmax,NTIMES=10;

//const int NMAX=1000000;

const int NMAX=1000;

double time_start,time,bandwidth,max;

float a[NMAX*8]; // equal to real*8 a[NTIMES] at fortran

struct MPI_Status status;

ierr=MPI_Init(&argc,&argv);

//ierr=MPI_Comm_size(MPI_COMM_WORLD, &size);

ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);

//time_start=MPI_Wtime();

n=0;

nmax=lmax=0;

while (n<=NMAX)

{

time_start=MPI_Wtime();

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

{

if (rank==0)

{

ierr=MPI_Send(&a,8*n,MPI_FLOAT, 1, 1, MPI_COMM_WORLD) ;

ierr=MPI_Recv(&a, 8*n, MPI_FLOAT, 1, 1, MPI_COMM_WORLD, &status) ;

} else

if (rank==1)

{

ierr=MPI_Recv(&a,8*n,MPI_FLOAT,0,1,MPI_COMM_WORLD,&status) ;

ierr=MPI_Send(&a,8*n,MPI_FLOAT,0,1,MPI_COMM_WORLD);

}

}

time=(MPI_Wtime()-time_start)/(2*NTIMES); // this is time for one way transaction

bandwidth=((double)8*n*sizeof(float))/ (1024*1024)/time;

if (max<bandwidth)

{max=bandwidth;

lmax=8*n*sizeof(float); }

if (rank==0)

{

if (!n) printf("Latency = %10.4d seconds\n", time);

else printf("%i bytes sent, bandwidth = %10.4d MB/s\n", 8*n*sizeof (float) ,bandwidth);

}

if (n==0) n=1; else n*=2;

}

// Finally print maximum bandwidth

if (rank==0) printf("Max bandwidth = %10.4d MB/s, length = %i bytes\n",max,lmax);

ierr=MPI_Finalize();

return 0;

}

Задание: Определите, насколько изменяется результат измерений, если количество количество повторений NTIMES увеличивать. Измените программу так, чтобы процесс 1 выводил NTIMES, при котором были получены результаты, выводимые процессом 0.