首页 > 解决方案 > MIP 中的来回通信是如何建立的?

问题描述

例如,我有一个根进程,它发送一些计算以由工作进程完成。但是因为我的 ( 4) 进程有限,所以我必须将工作量分担给所有进程,所以我发送了多次。我发现的解决方法是这样的:


    int me = MPI.COMM_WORLD.Rank();

    if(me == 0) {
        sendToWorkers(); //Sends more than once to workers.
    }
    else {
        while(true) {//wait indefinitely, accept data received from root process and work on it.
            MPI.COMM_WORLD.Recv(Buf, 0, Buf.length, MPI.INT, 0, 0);
            doTask(Buf);
        }
    }

现在问题出现了,我想将已完成处理的数据发送回根进程,但我不能做另一个while(true);。我确信必须有一种更优雅的方式来实现这一点。

编辑1:我想发送到根进程的原因是因为它更干净。但是,或者我可以只打印来自工作进程的计算解决方案,但由于交错,输出全部被破坏。print将方法声明为synchronized无效。

标签: javampimpj-express

解决方案


一个简单的解决方案是在任务分发结束时,master 必须向所有工作人员发送"FINISH/STOP/END"(任何自定义消息以指示任务结束)消息。获得完成消息的工作人员退出循环并将结果发送回主服务器。Master 可以启动一个包含所有任务的循环并等待这些结果。

从您显示的示例中,这是一个典型的主工作者模型用例。在这里,当您使用 向工作人员发送任务时,您的工作进程中MPI_Send()有一个对应的。MPI_Recv()接到任务后,执行doTask(Buf)。然后你再次进入循环。因此,在您的情况下,总而言之,您只有在计算之前收到的该级别的任务之后才会收到一个新任务,对吗?在这种情况下,主进程也可以等待任何已完成任务的回复,并可以基于此发送新任务。也许你可以考虑这种方法。如果您doTask使用线程,那么这将变得复杂。然后每个工作节点都必须跟踪其任务,并且在所有任务完成后,主节点应该开始一个循环并等待结果。

或者您可以使用多线程实现。您可以在 master 中使用单独的线程进行发送和接收。


推荐阅读