MPI如何阻止发送和接收工作?

时间:2018-04-01 12:44:01

标签: mpi

我正在阅读关于MPI阻止发送和接收的内容,还有一些我不确定的事情。

在进行一些研究时,我发现MPI阻止发送和接收的example(第6-7页)

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#define  MASTER 0

int main (int argc, char *argv[])
{
  int  numtasks, taskid, len, partner, message;
  char hostname[MPI_MAX_PROCESSOR_NAME];
  MPI_Status status;

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
  MPI_Comm_size(MPI_COMM_WORLD, &numtasks);

  /* need an even number of tasks  */
  if (numtasks % 2 != 0) {
   if (taskid == MASTER) 
    printf("Quitting. Need an even number of tasks: numtasks=%d\n", numtasks);
  } else {
    if (taskid == MASTER) 
      printf("MASTER: Number of MPI tasks is: %d\n",numtasks);

    MPI_Get_processor_name(hostname, &len);
    printf ("Hello from task %d on %s!\n", taskid, hostname);

    /* determine partner and then send/receive with partner */
    if (taskid < numtasks/2) {
      partner = numtasks/2 + taskid;
      MPI_Send(&taskid, 1, MPI_INT, partner, 1, MPI_COMM_WORLD);
      MPI_Recv(&message, 1, MPI_INT, partner, 1, MPI_COMM_WORLD, &status);
    } else if (taskid >= numtasks/2) {
      partner = taskid - numtasks/2;
      MPI_Recv(&message, 1, MPI_INT, partner, 1, MPI_COMM_WORLD, &status);
      MPI_Send(&taskid, 1, MPI_INT, partner, 1, MPI_COMM_WORLD);
    }

    /* print partner info and exit*/
    printf("Task %d is partner with %d\n",taskid,message);
  }

  MPI_Finalize();
}

我想知道的事情:

  • 一半的流程在收到之前发送,为什么会这样?
  • 如果所有人都在收到之前发送,会发生什么?

1 个答案:

答案 0 :(得分:1)

如果所有MPI任务MPI_Send()然后MPI_Recv(),那么它对MPI标准来说是不正确的。

原因是MPI_Send()可能会阻止匹配收到的匹配,在您的情况下,这将意味着死锁。

为了避免死锁,从而编写正确的程序,有以下几种选择:

  • 订单发送和接收(例如,一半发送然后接收,另一半接收然后发送)
  • 使用非阻止接收(例如,所有MPI任务MPI_Irecv(),然后是MPI_Send(),最后是MPI_Wait()
  • 使用MPI_Sendrecv(),这是最合适的,因为您的程序在两个任务之间交换数据。