我有一个 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 的问题。
我确信有更好的方法来做到这一点。有人有想法么?