【问题标题】:MPI_Rsend:how to know that a receive buffer is already postedMPI_Rsend:如何知道接收缓冲区已经发布
【发布时间】:2016-08-11 07:55:31
【问题描述】:

MPI_Rsend man papers,为了使用 MPI_Rsend,我们需要保证接收已经发布。如果在调用就绪发送之前没有发布接收是错误的。但是如何保证接收已经发布???。我尝试找到一些关于 MPI_Rsend 的示例,但我找不到任何东西。以及如何得到这个错误?
在此链接MPI_RSend_error 中,最后有人说:“不要使用 MPI_Rsend - 它是一种古老的东西,它的行为没有明确定义,并且它已被现代 MPI 中的所有协议优化所淘汰库”。那么,哪些 MPI 库完全实现了 RSend ?事实上,在某些算法中,使用 MPI_Rsend 会比 MPI_Send 提供更好的性能。
示例代码:

void AllGather_ring_RSend(void* data, int count, MPI_Datatype datatype,MPI_Comm communicator) 
{
  int me; 
  MPI_Comm_rank(communicator, &me); 
  int world_size; 
  MPI_Comm_size(communicator, &world_size);
  int next=me+1;
  if(next>=world_size)
      next=0;
  int prev=me-1;
  if(prev<0)
      prev=world_size-1;
  int i,curi=me;
  for(i=0;i<world_size-1;i++)
  {
     MPI_Rsend(data+curi*sizeof(int), count, datatype, next, 0, communicator);
     curi=curi-1;
     if(curi<0)
         curi=world_size-1;
     MPI_Recv(data+curi*sizeof(int), count, datatype, prev, 0, communicator, MPI_STATUS_IGNORE);     
  }
}
void main(int argc, char** argv) {
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    MPI_Init(&argc,&argv); 
    int world_rank,world_size,namelen; 
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    int* buff=(int*) malloc(world_size*sizeof(int));
      int i;
      for (i = 0; i < world_size; i++) {
          buff[i]=world_rank;
      }
      if(world_rank==0)
      for (i = 0; i < world_size; i++) 
         printf("%d\n",buff[i]);
    MPI_Barrier(MPI_COMM_WORLD); 
    AllGather_ring_RSend(buff,1,MPI_INT,MPI_COMM_WORLD);
    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Finalize();   
}

在这段代码中,接收过程是否已经发布???

【问题讨论】:

    标签: mpi openmpi hpc


    【解决方案1】:

    MPI 没有提供内置机制来检查远程队列是否已经发布了接收操作。由程序的逻辑来确保它是这种情况,例如让接收方以某种方式通知发送方(例如,通过消息或通过像MPI_(I)Barrier 这样的同步调用的完成)它已经发布了接收,因此可以安全地启动 ready 模式发送.

    正如我已经说过的,就绪模式发送已被现代网络和 MPI 实现的工作方式所淘汰。小消息已经异步发送(使用急切发送协议),而大消息的延迟节省(如果有的话)在很大程度上取决于平台、网络和实现。 MPI 标准中没有定义错误使用的就绪模式发送的结果,允许实现用标准模式替换就绪模式。因此很容易陷入本地实现的就绪发送行为并以不正确的 MPI 代码结束。此外,您甚至无法编写能够可靠地在所有 MPI 实现中产生错误的代码。

    将就绪模式实现为标准模式的 MPI 库示例是 Open MPI。 MPICH 通过在消息接收时检查匹配的接收并在未找到时返回错误来实现急切消息的就绪模式,这与标准发送到已发布的接收相比不会提供任何性能优势(如果我'我错了)。

    【讨论】:

    • 编辑后请检查我的代码。在这个代码中,远程排名是否已经发布了接收操作???
    • 如果MPI_Rsend 被阻塞,那么接收将永远不会被发布。如果MPI_Rsend 被缓冲,则存在竞争条件。
    • 接收已经发布,这意味着接收缓冲区分配有缓冲区大小 = 消息大小。因为接收缓冲区已分配。所有进程都等到所有缓冲区分配完毕,我认为 MPI_Rsend 将成功发送
    • 我不明白为什么“如果 MPI_Rsend 被阻塞,那么接收将永远不会被发布。如果 MPI_Rsend 被缓冲,那么就会出现竞争条件。”
    • 发布接收意味着致电MPI_RecvMPI_IrecvMPI_Recv_init 后跟MPI_Start。仅分配缓冲区是不够的。至于第二个问题,我认为很明显,所有等级都首先调用MPI_Rsend,然后才调用MPI_Recv。这是否会导致错误(如果有)取决于消息遍历网络所需的时间与 CPU 执行从MPI_RsendMPI_Recv 中间的代码所需的时间。
    猜你喜欢
    • 2014-10-28
    • 1970-01-01
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    • 2012-12-05
    相关资源
    最近更新 更多