Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
учебник_Вс.doc
Скачиваний:
14
Добавлен:
01.03.2025
Размер:
13 Мб
Скачать
☆

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

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

#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();

ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);

rbuf=l.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,l,MPI_FLOAT,0,5,MPI_COMM_WORLD); break;

} case 0: {

ierr=MPI_Probe(MPI_ANY_SOURCE,5,MPI_COMM_WORLD,Sstatus); if (status.MPI_S0URCE==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,1,5, MPI_COMM_WORLD,Sstatus);

} else // message from process 2 received first if (status.MPI_S0URCE==2) // ignore messages from other processes

{ ierr=MPI_Recv(&rbuf,1,MPI_FL0AT, l,5,MPI_C0MM_W0RLD,&status); ierr=MPI_Recv(&ibuf,1,MPI_INT, l,5,MPI_C0MM_W0RLD,&status);

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

ierr=MPI_Finalize(); ‘}

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

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

#include <stdio.h>

#include "mpi.h"

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

{

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

const int NMAX=1000 0 00;

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();

ierr=MPI_Comm_size (MPI_COMM__WORLD, &size) ;

ierr=MPI_Comm_rank(MPI_COMM_WORLD, Srank);

time_start=MPI_Wtime();

n=0;

nmax=lmax=0;

while (n<=NMAX)

{

time_start=MPI_Wtime(); for (int 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) ;

}

if (rank==l)

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

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

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

/*

Bandwidth = count of MBytes/time

count of MBytes= count of bytes/ 1M

(1M= 1024*1024 = 2Л10*2Л10=2**10 on fortran dialect :)

*/

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", 8*n*sizeof (float) ,bandwidth) ; } n=!n?l:2*n; // if (n==0) n=l; else n*=2;

}

// Finally print maximum bandwidth

if (rank==0)

printf("Max bandwidth = %10.4d MB/s, length = %i

bytes\n",lmax); ierr=MPI_Finalize(); }