如果您不知道会有消息,处理此问题的一种方法可能是让主进程充当消息队列,基本上处于无限接收循环中,直到所有任务都发送退出信号。
这样,您不必担心相邻任务之间的混合发送/接收计数,并且每个任务可以偶尔独立轮询主任务以查看是否有工作或消息。
这可能会有点复杂,尤其是消息队列,并确保在消息等待时两个任务会启动一个短的发送/接收会话,但它会阻止大量广播/全到-所有流量,这在时间上是出了名的昂贵。
如果主任务主要只处理消息状态,那么它应该是非常低摩擦的互连方式。
基本上对于任务0:
while (1){
MPI_recv(args);
if (any task has a message to send){ add it to the master's queue; }
if (any task is waiting to contact the task that is now polling for messages){ tell current task to initiate a Recv wait and signal the master that it is waiting; }
if (any other task is waiting for the current task to send to it){ initiate a send to that task; }
}
每个任务:
if (work needs to be sent to a neighbor){ contact master; master adds to queue; }
if (a neighbor wants to send work){ enter receive loop ; }
if (a neighbor is ready to receive work according to the master){ send work to it; }
或者:任务 3 有任务 8 的工作。任务 3 联系大师,并这么说。任务 3 继续其业务。任务 8 联系 Master,并看到它有来自任务 3 的工作待处理。任务 8 进入接收。任务 3(在某个轮询间隔)再次联系 master 以检查工作,并看到有一个任务等待工作。任务 3 启动发送。任务 3 为任何等待工作的剩余任务启动发送。程序继续。
现在,这有很多自己的警告。它是否有效取决于任务之间传递消息的频率,以及给定任务等待其邻居发送的时间。
最后,这可能并不比简单的 Alltoall() 更好。而且这个解决方案完全有可能是非常糟糕的。