OpenMPI:使用标签:这些可用于创建虚拟频道吗?

时间:2012-09-30 16:37:18

标签: tags openmpi

我在各个地方都提出了这个问题,包括OpenMPI邮件列表。到目前为止,我没有运气。所以,如果有人可以提供帮助,我将不胜感激,不管这个问题看起来多么愚蠢。

问题:

考虑在两个不同处理器上运行的两个进程A和B.没有其他 流程运行。进程A有两个要发送的消息,M1(大小:大,标签T1)和 M2(1字节,标记T2)。进程B使用MPI_Probe来选择性地过滤和 接收消息。是否保证进程B仍然可以接收消息M2, 什么时候没有MPI_Recv消息M1?考虑进程A首先发送M1。 所有进程都是单线程的。

此外,OpenMPI确保来自同一来源的两个不同消息 可以按任何顺序接收相同标签吗?

基本上,我想了解OpenMPI的系统缓冲区是否扮演了任何角色:如果一条消息设法将其填满,则可能永远不会收到来自同一来源但带有另一个标记的另一条消息。正确的吗?

非常感谢任何想法。

Devendra

1 个答案:

答案 0 :(得分:2)

我在Open MPI用户列表中回复了您,但也会在此处发布,以防其他人认为它有用。我相信Jeff Squyres已经在Open MPI邮件列表中回答了你的问题,或者至少暗示了可能出现的问题。 MPI消息按发送顺序接收,但仅在特定(标记,通信器)元组内接收。这基本上意味着:

  • 在同一个传播者中,如果他们携带不同的标签,您可以无序接收消息;
  • 如果在不同的环境(传播者)中传播带有相同标签的消息,则可能无序接收。

但是这里有一个问题:如果尚未发布发送操作,则无法收到消息。如果您有两个连续的发送操作,则必须确保第一个不会永久阻止。标准MPI发送操作MPI_Send可以以各种方式实现(标准没有详细说明如何),但在大多数MPI实现中,它的行为类似于针对非常小的消息的缓冲发送,以及类似于针对较大消息的同步发送。如果您的发件人流程中有以下两个电话:

MPI_Send(largedata, largecount, MPI_INT, dest, tag1, MPI_COMM_WORLD);
MPI_Send(smalldata, smallcount, MPI_INT, dest, tag2, MPI_COMM_WORLD);

可能会发生第一个MPI_Send实际上表现为同步的情况,即除非匹配的接收操作是在接收方旁边发布的,否则它不会返回。假设你的接收者代码是:

MPI_Probe(src, tag2, MPI_COMM_WORLD, &status);
MPI_Recv(largedata, largecount, MPI_INT, src, tag1, MPI_COMM_WORLD, &status);

这很可能是死锁,因为MPI_Probe是一个阻塞调用,即在发布匹配的发送之前它不会返回,即第二个MPI_Send必须执行,这只会发生在第一次发送已经返回,但除非接收器中的MPI_Recv被执行,否则不会发生...我想你明白了这个想法

为防止死锁,您可以修改发件人的代码以使用非阻止发送:

MPI_Request req;
MPI_Isend(largedata, largecount, MPI_INT, dest, tag1, MPI_COMM_WORLD, &req);
MPI_Send(smalldata, smallcount, MPI_INT, dest, tag2, MPI_COMM_WORLD);
MPI_Wait(&req, MPI_STATUS_IGNORE);

使用非阻塞操作,send调用立即返回,操作在后台继续,因此第二次发送将在此之后立即执行。现在会有两条待处理的消息,它们可以按任何顺序接收,因为它们带有不同的标签。