我正在使用MPI解决负载平衡问题:主进程将任务发送到从属进程并在计算和收回其作业时收集结果。 由于我想尽可能地提高性能,我使用非阻塞通信:Master发送几个任务,然后等待一个进程发回其响应,以便主服务器可以向其发送额外的工作,等等。
我使用MPI_Waitany(),因为我事先并不知道哪个从属进程响应,然后我从状态获取发件人,我可以将新作业发送给它。
我的问题是,我收到的发件人有时是错的(不在MPI_COMM_WORLD中),程序崩溃了;其他时候它工作正常。
这是代码。谢谢!
//master
if (rank == 0) {
int N_chunks = 10;
MPI_Request request[N_chunks];
MPI_Status status[N_chunks];
int N_computed = 0;
int dest,index_completed;
//initialize array of my data structure
vec send[N_chunks];
vec recv[N_chunks];
//send one job to each process in communicator
for(int i=1;i<size;i++){
MPI_Send( &send[N_computed], 1, mpi_vec_type, i, tag, MPI_COMM_WORLD);
MPI_Irecv(&recv[N_computed], 1, mpi_vec_type, i, tag, MPI_COMM_WORLD,
&request[N_computed]);
N_computed++;
}
// loop
while (N_computed < N_chunks){
//get processed messages
MPI_Waitany(N_computed,request,&index_completed,status);
//get sender ID dest
dest = status[index_completed].MPI_SOURCE;
//send a new job to that process
MPI_Send( &send[N_computed], 1, mpi_vec_type, dest, tag, MPI_COMM_WORLD);
MPI_Irecv(&recv[N_computed], 1, mpi_vec_type, dest, tag, MPI_COMM_WORLD,
&request[N_computed]);
N_computed++;
}
MPI_Waitall(N_computed,request,status);
//close all process
printf("End master\n");
}
答案 0 :(得分:1)
您没有正确使用MPI_Waitany()
。
应该是
MPI_Status status;
MPI_Waitany(N_computed,request,&index_completed,&status);
dest = status.MPI_SOURCE;
注意:
MPI_Wait()
最后size - 1
次请求MPI_Request request[size-1];
,从而节省一些内存答案 1 :(得分:0)
我忘了在初始帖子中添加一行,我等待所有待处理的请求:顺便说一句,如果我每次在Waitany初始化新状态时主进程崩溃;我需要跟踪哪些进程仍处于待处理阶段才能等待适当的次数... 谢谢你的方式
编辑:现在即使我发现它不是很聪明,它也能正常工作;是否有可能在开始时初始化MPI_Status数组,而不是每次等待之前都这样做?//master
if (rank == 0) {
int N_chunks = 10;
MPI_Request request[size-1];
int N_computed = 0;
int dest;
int index_completed;
//initialize array of vec
vec send[N_chunks];
vec recv[N_chunks];
//initial case
for(int i=1;i<size;i++){
MPI_Send(&send[N_computed], 1, mpi_vec_type, i, tag, MPI_COMM_WORLD);
MPI_Irecv(&recv[N_computed], 1, mpi_vec_type, i, tag, MPI_COMM_WORLD, &request[N_computed]);
N_computed++;
}
// loop
while (N_computed < N_chunks){
MPI_Status status;
//get processed messages
MPI_Waitany(N_computed,request,&index_completed,&status);
//get sender ID dest
dest = status.MPI_SOURCE;
MPI_Send(&send[N_computed], 1, mpi_vec_type, dest, tag, MPI_COMM_WORLD);
MPI_Irecv(&recv[N_computed], 1, mpi_vec_type, dest, tag, MPI_COMM_WORLD, &request[N_computed]);
N_computed++;
}
//wait other process to send back their load
for(int i=0;i<size-1;i++){
MPI_Status status;
MPI_Waitany(N_computed, request, &index_completed,&status);
}
//end
printf("Ms finish\n");
}