MPI_Isend / MPI_Recv与MPI_Send / MPI_Irecv

时间:2018-11-08 08:56:44

标签: mpi

对于MPI中的异步通信,在性能,可靠性,可读性等方面,以下哪个更好:

  • MPI_Isend带有缓冲区,然后在接收器准备就绪后发送MPI_Iprobe和MPI_Recv,或者
  • 带有缓冲区的MPI_Irecv(这样总是有MPI_Irecv,并且有足够的缓冲区发布),然后在发送方准备就绪时发送MPI_Send吗?

通信场景是必须异步交换数据,到达时间无关紧要,并且两个进程都有工作量。仅考虑整体性能(尤其是没有阻塞)。

下面是一个最小的工作示例(我没有包括工作量,因此时间安排可能没有意义)。

#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char const *argv[]) {
  MPI_Init(NULL, NULL);
  int world_size, world_rank;

  MPI_Comm_size(MPI_COMM_WORLD, &world_size);
  MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);

  if (world_rank == 0 && world_size != 2) {
    fprintf(stderr, "This example requires two MPI processes.\n");
    MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
  }

  /* Non Blocking Send */
  int buf[100] = {0};

  MPI_Barrier(MPI_COMM_WORLD);
  double time = MPI_Wtime();
  if (world_rank == 1) {
    MPI_Request request;
    MPI_Isend(buf, 100, MPI_INT, 0, 0, MPI_COMM_WORLD, &request);
    MPI_Wait(&request, MPI_STATUS_IGNORE);
  } else {
    MPI_Recv(buf, 100, MPI_INT, 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  }
  time = MPI_Wtime() - time;
  printf("rank = %d, time = %f sec\n", world_rank, time);
  MPI_Barrier(MPI_COMM_WORLD);

  usleep(100);
  if (world_rank == 0) {
    printf("---\n");
  }

  /* Non Blocking Receive */
  MPI_Barrier(MPI_COMM_WORLD);
  time = MPI_Wtime();
  if (world_rank == 1) {
    MPI_Send(buf, 100, MPI_INT, 0, 0, MPI_COMM_WORLD);
  } else {
    MPI_Request request;
    MPI_Irecv(buf, 100, MPI_INT, 1, 0, MPI_COMM_WORLD, &request);
    MPI_Wait(&request, MPI_STATUS_IGNORE);
  }
  time = MPI_Wtime() - time;
  printf("rank = %d, time = %f sec\n", world_rank, time);
  MPI_Barrier(MPI_COMM_WORLD);

  MPI_Finalize();
  return 0;
}

在我的机器上,这会生成:

rank = 0, time = 0.000035 sec
rank = 1, time = 0.000036 sec
---
rank = 0, time = 0.000035 sec
rank = 1, time = 0.000026 sec

感谢您的回答,祝您愉快:)

0 个答案:

没有答案