忙于等待 MPI_Iprobe 和 MPI_Testsome 是否有效?

计算科学 mpi
2021-12-26 00:48:23

我有一个 MPI 应用程序,它需要在专用通信线程内异步响应传入消息和请求完成。执行此操作的明显方法是交替调用 MPI_Iprobe 和 MPI_Testsome 的繁忙等待。如果我这样做,我应该担心性能吗?只使用两个线程并吃掉上下文切换时间会更好吗?

如果架构非特定的答案不合理,我会选择 BlueGene/Q 或 Cray XE6。

不幸的是(就 MPI_Testsome 成本而言),我希望一次有 O(100) 个请求处于活动状态。

笔记:

  1. 我的内存有限,因此尽快检测到已完成的请求很重要。完成的请求可能会释放足够的空间来在其他线程上安排更多计算。
  2. 传入的消息大小不一,而且我没有足够的内存来为所有消息分配缓冲区,所以我不能切换到 MPI_Irecvs 而不是 MPI_Iprobes。
  3. 遗憾的是,MPI 不允许您使用传入消息大小的上限来执行 MPI_Irecv,因为这可以完美地解决我的问题。
3个回答

正如 Jeremiah W. 在上面的注释中提到的,您的“注释 3”实际上是 MPI 明确支持的。您始终可以发布比您实际发送的消息更大的接收缓冲区。

所以这很好:

if (rank == 0) {
    MPI_Request req;
    MPI_Status status;
    int num_received;
    MPI_Irecv(recvbuf, 100, MPI_DOUBLE, 1, 1234, MPI_COMM_WORLD, &req);
    MPI_Wait(&req, &status);
    MPI_Get_count(&status, MPI_DOUBLE, &num_received);
    /* num_received should now contain 5 */
}
else if (rank == 1) {
    MPI_Send(sendbuf, 5, MPI_DOUBLE, 0, 1234, MPI_COMM_WORLD);
}

如果您可以使用MPI_Irecv消息大小的上限,为什么不每次都发送那个字节数(即填充消息)?

很难说 1 个线程在做IprobeTestsome每个线程都比一个线程更好或更差。这将非常依赖于使用情况。

实现这两种方法并在野外比较它们有多难?

只是进一步优化以摆脱使用接收缓冲区的上限(如前所述):

您正在使用 MPI_Iprobe,它还会返回消息的 MPI_Status。为什么不使用具有此状态和 MPI_datatype 的 MPI_Get_count() 来查询要接收的消息的大小并分配确切大小的缓冲区?