Параллельное программирование: Учебное пособие, страница 102

Process 1 received after wait 3.14159012

Process 1 received after wait 2.71828008

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

Текст 5.12.а. Использование неблокирующих операций обмена

#include “mpi.h”

#include <stdio.h>

main(int argc, char* argv[])

 {

  int         rank, tag, cnt;

  int         status(MPI_STATUS_SIZE);

  MPI_Request request;

  float       sndbuf[5] = {1., 2., 3., 4., 5.};

  float       rcvbuf[5];

  cnt = 5;

  tag = 0;

  MPI_Init(&argc, &argv);

  MPI_Comm_rank(MPI_COMM_WORLD, rank);

  IF(rank == 0)

    {

      MPI_Isend(*sndbuf, cnt, MPI_REAL, 1, tag,

                             MPI_COMM_WORLD, request);

      Printf("Process ", rank, " send before wait",

                                              sndbuf);

      MPI_Wait(request, status);

      Printf("Process ", rank, " send after wait",

                                              sndbuf)

    }

  else

    {

      MPI_Irecv(*rcvbuf, cnt, MPI_REAL, 0, tag,

                              MPI_COMM_WORLD, request);

      Printf("Process ", rank, " received before wait",

                                               rcvbuf);

      MPI_Wait(request, status);

      Printf("Process ", rank, " received after wait",

                                               rcvbuf);

    }

MPI_Finalize();

 }

Результат выполнения этой программы:

mpiexec –host -machinefile -n 2 – myprogr

Process 0 send before wait 1. 2. 3. 4. 5.

Process 0 send after wait 1. 2. 3. 4. 5.

Process 1 received before wait 5.73971851E-42 0. 4.12288481E-34 2.12725878 2.08672428

Process 1 received after wait 1. 2. 3. 4. 5.

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

Текст 5.12. Параллельное интегрирование методом трапеций

#include <stdio.h>

#include "mpi.h"

main(int argc, char** argv)

{

intmy_rank;   /* Ранг моего процесса */

intp;         /* Число процессоров */

  float a;         /* Нижняя граница интегрирования */

  float b;         /* Верхняя граница интегрирования */

  int   n;         /* Полное число интервалов */

floath;         /* Шаг интегрирования */

floatlocal_a;   /* Нижний предел моего интервала */

floatlocal_b;   /* Верхний предел моего интервала */

intlocal_n;   /* Число интервалов на моем            */

/* участке интегрирования                */

  float integral;  /* Интеграл на моем интервале        */

  float total;     /* Общий интеграл */

  int   source;    /* Источник значения интеграла      */

  int   dest = 0;  /* Все передаются процессору 0      */

inttag = 0;

MPI_Statusstatus;         /* Статус выполнения передач */

            /* Объявление функции ввода исходных данных */

void Get_data(float* a_ptr, float* b_ptr,

                     int* n_ptr, int my_rank, int p);

/* Объявление функции вычисления локального интеграла */

float Trap(float local_a, float local_b,

int local_n, float h);

  MPI_Init(&argc, &argv);          /* Инициализация MPI */

/* Имена процессоров */

MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

  MPI_Comm_size(MPI_COMM_WORLD, &p); /* Число процессоров */

  Get_data(&a, &b, &n, my_rank, p);  /* Ввод данных */

  h = (b-a)/n;                      /* шаг интегрирования */

local_n = n/p;            /* число интервалов на процессор */

local_a = a + my_rank*local_n*h;     /* границы локаль-*/

  local_b = local_a + local_n*h;       /* ного интервала */

/* вычисление локального интеграла */

  integral = Trap(local_a, local_b, local_n, h);

  if (my_rank == 0)       /* Сложение частных интегралов*/

{

      total = integral;

      for (source = 1; source < p; source++)

        {           /* Процессор 0 принимает частные значения */

          MPI_Recv(&integral, 1,MPI_FLOAT, source,tag,

                             MPI_COMM_WORLD, &status);

          total = total + integral;     /* Накопление */