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

Определение характеристик таймера

В этой программе на каждом процессе определяются две характеристики системного таймера: его разрешение и время, требуемое на замер времени (для усреднения получаемого значения выполняется NTIMES замеров). Также в данном примере показано использование процедуры MPI_GET_PROCESSOR_NAME.

Пример 3:

#include <stdio.h>

#include "mpi.h"

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

{

int n,ierr,rank,len,i,NTIMES=100;

char name[MPI_MAX_PROCESSOR_NAME];

double time_start,time_finish,tick;

MPI_Init(&argc,&argv);

ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);

ierr=MPI_Get_processor_name(name, &len);

name[len]=0;

tick=MPI_Wtick();

time_start=MPI_Wtime();

for (n = 0; n<NTIMES; n++) time_finish=MPI_Wtime();

ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);

printf("Processor %s, process %i: tick = %d, time = %d\n",name,rank,tick,(time_finish-time_start)/(double)NTIMES);

ierr=MPI_Finalize(); }

Приём и передача сообщений

Передача сообщения использована буферизация. Для буферизации выделяется массив buf, после завершения пересылки он освобождается. Размер необходимого буфера определяется размером сообщения (одно целое число – 4 байта) плюс значение константы MPI_BSEND_ OVERHEAD.

Пример 4:

#include <stdio.h>

#include "mpi.h"

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

{

const int BUFSIZE=MPI_BSEND_OVERHEAD+4;

unsigned char buf[BUFSIZE];

int rank,ierr,ibufsize,rbuf;

struct MPI_Status status;

ierr=MPI_Init(&argc,&argv);

ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if (rank==0) {

ierr=MPI_Buffer_attach(buf,BUFSIZE);

ierr=MPI_Bsend(&rank,1,MPI_INT,1,5,MPI_COMM_WORLD);

// sending variable rank

ierr=MPI_Buffer_detach(&buf, &BUFSIZE);

}

if (rank==1)

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

printf("Process 1 received %i from process %i\n",rbuf, status.MPI_SOURCE);

}

ierr=MPI_Finalize();

}

Ниже приведен пример программы, в которой нулевой процесс посылает сообщение процессу с номером один и ждет от него ответа. Если программа будет запущена с большим числом процессов, то реально выполнять пересылки все равно станут только нулевой и первый процессы. Остальные процессы после их инициализации процедурой MPI__Init напечатают начальные значения переменных а и b, после чего завершатся, выполнив процедуру MPI_FINALIZE.

Пример 5:

#include <stdio.h>

#include "mpi.h"

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

{

int ierr,size,rank;

float a,b;

MPI_Status status;

ierr=MPI_Init(&argc,&argv);

ierr=MPI_Comm_size(MPI_COMM_WORLD, &size);

ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank);

a=b=0;

if (rank==0)

{ ierr=MPI_Send(&b,1,MPI_FLOAT,1,5,MPI_COMM_WORLD);

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

} else

if (rank==1)

{

a=2;

ierr=MPI_Recv(&b,1,MPI_FLOAT,0,5,MPI_COMM_WORLD,&status);

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

printf("Process %i a = %lf b = %lf\n",rank,a,b); }

ierr=MPI_Finalize();

}

В следующем примере каждый процесс с четным номером посылает сообщение своему соседу с номером на единицу большим. Дополнительно поставлена проверка для процесса с максимальным номером, чтобы он не послал сообщение несуществующему процессу. Значения переменной b изменятся только на процессах с нечетными номерами.

Пример 6:

#include <stdio.h>

#include "mpi.h"

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

{

int ierr,size,rank,a,b;

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

a=rank;

b=-1;

if (rank%2==0)

{

if (rank+1<size)

ierr=MPI_Send(&a, 1, MPI_INT, rank+1, 5, MPI_COMM_WORLD);

}

else ierr=MPI_Recv(&b,1,MPI_INT,rank-1,5,MPI_COMM_WORLD,&status);

printf ("Process %i a = %i b = %i\n",rank,a,b) ;

ierr=MPI_Finalize (); }

Задание: Измените данную программу так, чтобы нулевой процесс не посылал сообщений и запустите её с числом процессов, равным номеру вашего варианта.

Процессы приложения в приводимой ниже программе разбиваются на две непере­секающиеся примерно равные группы groupl и group2. При нечетном числе процессов в группе group2 может оказаться на один процесс больше, тогда последний процесс из данной группы не должен обмениваться данными ни с одним процессом из группы groupl. С помощью вызовов процедуры MPI_Group_translate_ranks каждый процесс находит процесс с тем же номером в другой группе и обменивается с ним сообщением через коммуникатор MPl_COMM_WORLD при помощи вызова процедуры MPI_Sendrecv. В конце программы не нужные далее группы уничтожаются с помощью вызовов процедур MPI_GROUP_FREE.

Пример 7:

#include <stdio.h>

#include "mpi.h"

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

{

int ierr,rank,i,size,size1;

const int n=1000;

int a[4],b[4];

int ranks[128], rank1, rank2, rank3;

MPI_Status status;

MPI_Group group,group1,group2;

ierr=MPI_Init(&argc,&argv);

ierr=MPI_Comm_size(MPI_COMM_WORLD,&size);

ierr=MPI_Comm_rank(MPI_COMM_WORLD, &rank) ;

ierr=MPI_Comm_group(MPI_COMM_WORLD, &group);

size1=size/2;

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

ranks[i]=i;

ierr=MPI_Group_incl(group,size1,ranks, &group1);

ierr=MPI_Group_excl(group,size1,ranks, &group2);

ierr=MPI_Group_rank (group1, &rank1);

ierr=MPI_Group_rank(group2,&rank2);

if (rank1==MPI_UNDEFINED) // we are in second half

{ if (rank2<size1)

ierr=MPI_Group_translate_ranks(group1,1,&rank2,group,&rank3); else rank3=MPI_UNDEFINED;

}

else // in first half

ierr=MPI_Group_translate_ranks(group2,1,&rank1,group,&rank3);

a[0]=rank;

a[1]=rank1;

a[2]=rank2;

a[3]=rank3;

if (rank3!=MPI_UNDEFINED)

ierr=MPI_Sendrecv(a,4,MPI_INT,rank3,1,b,4,MPI_INT,rank3,1,MPI_COMM_WORLD,&status);

ierr=MPI_Group_free(&group) ;

ierr=MPI_Group_free(&group1);

ierr=MPI_Group_free(&group2);

printf ( "Process %i a=[",rank);

for ( i=0;i<4;i++) printf("%i ",a[i]);

printf ("] b=[");

for ( i=0;i<4;i++) printf ("%i ",b[i]);

printf("]\n");

ierr=MPI_Finalize();

}

Задание: Измените программу так, чтобы передаваемые сообщения содержали номер передающего процесса и ваше имя.