【发布时间】:2020-12-05 18:39:19
【问题描述】:
我知道关于 MPI 发送和接收的不同模式有很多问题和答案,但我相信我的不同,或者我根本无法将这些答案应用于我的问题。
无论如何,我的情况如下。该代码适用于具有潜在数千个内核的高性能集群,并组织成一个多维网格。在我的算法中,需要执行两个连续的操作,我们称它们为 A 和 B,其中 A 在 之前乙。简要说明如下:
A:每个处理器都有多个缓冲区。它必须将这些缓冲区中的每一个发送到一组特定的处理器。对于要发送的每个缓冲区,接收处理器的集合可能不同。发送是操作A的最后一步。
B:每个处理器从一组处理器接收一组缓冲区。操作 B 将在收到 所有 个缓冲区后对这些缓冲区进行操作。该操作的结果将存储在一个固定的位置(既不在发送缓冲区,也不在接收缓冲区)
还给出了以下属性:
- 在A中,每个处理器都可以计算要发送到哪些处理器,并且它还可以计算相应的标签,以防一个处理器从同一个发送处理器接收到多个缓冲区(这很有可能) .
- 在B中,每个处理器还可以计算它将从哪些处理器接收,以及发送消息时使用的相应标签。
- 每个处理器都有自己的发送缓冲区和接收缓冲区,它们是不相交的(即没有处理器也将其发送缓冲区用作接收缓冲区,反之亦然)。
- A 和 B 在 A 之前和 B 之后的其他操作中循环执行。我们可以确保在下一次循环迭代之前不会再次使用发送缓冲区,在 A 中填充新数据,并且在下一次迭代之前不会再次使用接收缓冲区,其中它们用于在操作 B 中接收新数据。
- 如果可能,A 和 B 之间的过渡应该是一个同步点,即我们要确保所有处理器都进入 B同时
要发送和接收,A 和 B 都必须自己使用(嵌套)循环来发送和接收不同的缓冲区。但是,我们不能对这些发送和接收语句的顺序做出任何假设,即对于任何两个缓冲区 buf0 和 buf1,我们不能保证如果 buf0 之前被某个处理器接收buf1,即buf0 也在buf1 之前发送。请注意,此时,由于确定接收/发送处理器集的复杂性,还不能选择使用 MPI_Broadcast 等组操作。
问题:我应该使用哪种发送和接收模式?我已经阅读了很多关于这些不同模式的不同内容,但我无法真正理解它们。最重要的属性是无死锁,其次是性能。我倾向于在 A 中使用 MPI_Isend() 而不检查请求状态,并在 B 的循环中再次使用非阻塞 MPI_IRecv(),然后使用 @987654330 @ 以确保接收到所有缓冲区(因此,所有缓冲区也已发送并且处理器已同步)。
这是正确的方法,还是我必须使用缓冲发送或完全不同的方法?我在 MPI 方面没有大量经验,文档也对我没有太大帮助。
【问题讨论】:
标签: c++ performance mpi deadlock