当我想在异步发送之后完全释放资源时,MPI_Bsend 好吗?
这会不会:

MPI_Bsend(&array[0],...)
delete[] array;

阻止我删除我想发送的内存(问题是,当适当的 recv 开启时,数组可能已经被删除)?

更新:
void RectMPIAngleFiller::setglobalFillerbounds1() {

    int_t SIZE = getSolver()->getNumInterpolators() * procnums;
    int_t gridnums = getSolver()->getNumGrids();
    if (layer == 1) {
      if (local_rank == 0) {
    MPI_Isend(&rank_size, 1, MPI_INT, 0, gridnum, MPI_COMM_WORLD);
      }
    } else if (layer == 0) {
      int_t fillernumber = getSolver()->getNumInterpolators();
      int_t local_fillernum = fillernum % fillernumber;
      if (local_rank == 0 && local_fillernum == 0) {
    int_t * incomeSizes = new incomeSizes[gridnums];
    incomeSizes[gridnum] = getSolver()->getNumInterpolators();

    for ( int_t i = 0; i < gridnums; i++) {
      if (i != gridnum)
        MPI_Irecv(&incomeSizes[i], 1, MPI_INT, MPI_ANY_SOURCE, i, MPI_COMM_WORLD, &request);
    }

      }
   }
}

例如,我现在有一个这样的函数(现在可能不正确),它从许多进程中收集大小,这些进程可能相同但运行在不同的类实例上,这就是为什么一切都与发送有关。

这个函数在每个实例的外循环中运行,我希望它在整个循环之后完成。

现在它只接收大小,我不想要这个并且想要删除一些内部数组并根据同一函数中接收到的大小调整它们的大小。如果我有非常大的数组,Isend 中的内部缓冲区太小而无法存储所有信息。

最佳答案

缓冲发送和非阻塞发送之间的区别在 MPI 中有点微妙。在实践中,它们都可以用来避免死锁,因为这两个例程都在消息传递之前将控制权返回给用户(或者更确切地说,它们将始终返回给用户,但此时无法保证消息已传递)。实际上,这意味着两者都不需要等待发布匹配的接收,这有助于避免死锁。

但是, MPI_Bsend 保证数据已复制到缓冲区。由用户确保他们通过 MPI_Buffer_attach 提供了足够的内存,以便缓冲所有未完成的消息。这是一条消息还是多条消息取决于程序的逻辑。

MPI_Isend 不保证消息已被复制到缓冲区。心智模型是发送已被推迟到以后 - 您已经要求 MPI 在将来方便的某个时间发送消息。您必须等待相关联的请求以确保 MPI_Send 已完成。

  • 当 MPI_Bsend 返回时,释放发送缓冲区是安全的
    保证已被复制到用户提供的缓冲区中。
  • 当 MPI_Isend 返回时,释放发送缓冲区是不安全的。
  • 当 MPI_Wait(&request, &status) 返回时,解除分配是安全的
    发送缓冲区。这是因为要么数据已被复制到
    缓冲区(系统缓冲区,不是您通过 Buffer_attach 提供的缓冲区)
    或者因为它已被安全地传送到匹配的 MPI_Recv。

  • MPI 可以自由选择是否缓冲 MPI_Send。实际上,小消息会被缓冲,而大消息则不会。

    尽管 MPI_Ibsend 存在是为了完整性,但我想不出真正的用例。原则上,它可以在消息被复制到用户提供的缓冲区之前返回,所以你不能在等待之后释放发送缓冲区。那么您可以将用户代码与拷贝重叠吗?在实践中似乎有点无意义。

    关于c++ - MPI - Bsend 用法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42606441/

    10-13 08:17