例如,我有一个根进程,该进程发送一些要由工作进程完成的计算。但是,由于我的进程(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:之所以要发送到root进程,是因为它更干净。但是,可替代地,我可以仅打印工作进程中的计算出的解决方案,但由于交织,输出全部被破坏了。将print方法声明为synchronized不起作用。

最佳答案

一种简单的解决方案是在任务分发结束时,主服务器必须向所有工作人员发送"FINISH/STOP/END"(任何自定义消息以表明任务已结束)消息。收到完成消息的工作人员退出循环,并将结果发送回主服务器。师父可以开始执行总任务的循环,然后等待这些结果。

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

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

10-08 01:43