我正在尝试在这里实现一个工作池。我应该向奴隶进程发送总数为100的数字。然后,每个从属进程向主进程返回一些内容,主进程将另一个不同的数字发送给从属进程。这一直持续到所有100次迭代结束。
我的程序陷入无限循环,我认为是由于MPI_Send和MPI_Recv的映射不正确。我无法弄清楚我做错了什么。我花了好几个小时研究这个,但无济于事。我是MPI和编程的新手。代码如下:
if(rank == 0) {
int i,iteration = 0, a=0,inside=0,temp=0;
for(i = 1; i < slaves; i++) {
MPI_Send(&iteration,1,MPI_INT,i,0,MPI_COMM_WORLD);
MPI_Send(&a,1,MPI_INT,i,1,MPI_COMM_WORLD);
iteration++;
}
while(iteration < 100+slaves){
MPI_Recv(&temp,1,MPI_INT,MPI_ANY_SOURCE,0, MPI_COMM_WORLD, &status);
if(iteration < 100) {
MPI_Send(&iteration,1,MPI_INT,status.MPI_SOURCE,0,MPI_COMM_WORLD);
MPI_Send(&a,1,MPI_INT,status.MPI_SOURCE,1,MPI_COMM_WORLD);
}
iteration++;
inside = inside + temp;
}
}
else {
int iteration=0,count=0;
if(iteration < 100) {
MPI_Recv(&iteration,1,MPI_INT,0,0,MPI_COMM_WORLD,&status);
MPI_Recv(&count,1,MPI_INT,0,1,MPI_COMM_WORLD,&status);
MPI_Send(&count,1,MPI_INT,0,0,MPI_COMM_WORLD);
}
}
答案 0 :(得分:3)
你也需要在你的奴隶队伍中循环。现在,您将iteration
和a
从主服务器发送到从服务器,将count
从服务器发送回主服务器,然后主服务器尝试发送iteration
来自a
循环内的while
和else
,而奴隶们已经愉快地退出while
区块并继续他们的快乐方式。要么摆脱主进程中的{{1}}循环,以便它不发送从站永远不会收到的东西,或者在从进程中添加一个循环,以便它们能够正确地接收该数据。
答案 1 :(得分:2)
MPI中最重要的事情之一是理解,通常每个进程都执行相同的程序。这使得mpi_rank
成为您最好的朋友之一,因为您需要它来区分每个流程必须完成的不同任务。
另一个要理解的重点是MPI中的阻塞/非阻塞通信是如何工作的。在这里,我们使用阻止通信(MPI_Send()
和MPI_Recv()
)。这意味着一个过程将停留在MPI_Recv()
之类的函数调用中,并等到通信伙伴将达到它的对应关键字&#34; (MPI_Send()
,向我发送信息)。
您的程序卡住的事实很好地表明没有相同数量的MPI_Send()
和MPI_Recv()
调用:某个进程仍在等待接收消息/能够发送消息消息。
对于你的例子,我尝试做这样的事情:
while( iterations < 100 ){
// in general every process has to do something for 100 times,
// but we have to have to distinguish between master and slaves.
if( mpi_rank == 0 ){
// The master process...
for( int slave_rank = 1; slave_rank < mpi_size; slave_rank++ ){
// ... has to send, receive and send once again something to/from every(!) slave, ...
MPI_Send( [one int to slave_rank] );
MPI_Recv( [one int from slave_rank] );
MPI_Send( [another int to slave_rank] );
}
}
else{
//... while the slaves just have to receive, send and receive again from/to one process (the master)
MPI_Recv( [one int from master] );
MPI_Send( [one int to master] );
MPI_Recv( [another int from master] );
}
iterations++;
}
你的任务听起来像:Master发送int到slave#1,#2,#3 .....,然后他从#1,#2,#3 ....收到,然后他发送另一个int到#1,#2,#3。你可能会认识到你必须循环遍历所有奴隶等级三次。
这个解决方案是不同的(虽然结果是相同的),但更短:Master将int发送到slave#1,然后从slave#1接收int,然后将另一个int发送到slave#1。之后,为奴隶#2,#3,#4重复同样的事情....这样我们只需要循环所有奴隶等级一次。