我有一个MPI程序,每个处理器执行以下操作:
执行昂贵的操作。
如果我需要远程存储任何东西(可以在任何其他处理器上),请在缓冲区中排队请求并继续。
如果缓冲区已满,请进入通信阶段。
在通信阶段,具有完整缓冲区的处理器应该发送一些缓冲信息,然后返回“昂贵的操作”。当然,直到至少有两个处理器进入通信阶段并且可以执行MPI命令时才会发生这种情况。
目前我正在通过暂停来处理这个问题,直到所有处理器进入通信阶段,然后做类似的事情,
MPI_Allgather(Num_send_local,NTask,MPI_INT,Num_send_global,NTask,MPI_INT,MPI_COMM_WORLD);
其中Num_send_local是一个长度为NTask的数组,包含要发送到每个任务的事物数量(因此Num_send_global就是NTask * NTask)。
这很有效,但是经常会导致大量资源浪费,因为可以互相通信的处理器会等待每个人都准备好发送。
我想要发生的事情是,只要两个处理器进入通信阶段就会发生通信,但我在实现它时遇到了麻烦。我尝试了以下内容:
//Tell everyone I'm in the comm phase now
for(i=0;i<NTask;i++)
{
if(Task==i)
continue;
MPI_Isend(&Num_send_local[i],1,MPI_INT,i,0,MPI_COMM_WORLD,&request[i]);
}
MPI_Recv(&local,MPI_INT,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
remote_partner = status.MPI_SOURCE;
//Do stuff between Task and remote_partner...
但是这遇到了remote_partner收到别人的发送请求而不是Task的问题。
我确信有更好的方法可以做到这一点。有人有什么想法吗?
答案 0 :(得分:0)
这一切都取决于您的应用程序的规模,并且一如既往地,衡量性能是关键(当您至少有一些工作版本时)。您可以尝试主从方法,其中一个进程处理将工作分配给空闲从属进程。 Stackoverflow和更大的Internet在实现主从并行程序方面拥有大量资源。
答案 1 :(得分:0)
我认为你所寻找的东西可以在这个相当冗长的主 - 从模型的here例子中找到。当奴隶的工作完成后,奴隶将发送一个结果,而主人知道要向奴隶发送另一轮工作。