MPI_Waitany()或带有MPI_ANY_源的MPI_Recv()?

MPI_Waitany()或带有MPI_ANY_源的MPI_Recv()?,mpi,hpc,Mpi,Hpc,背景: 在我的程序中,主进程为从进程分配工作。一旦从进程完成工作,它就会向主进程请求更多的工作。主程序将更多的工作分配给从程序,程序继续运行 我编写程序的方式是,主进程使用MPI_Recv和MPI_ANY_源来接收从节点的工作 /* Allot some work to all the slaves (seed) */ while (istheremorework()) { /* Master receives slaves work*/ MP

背景: 在我的程序中,主进程为从进程分配工作。一旦从进程完成工作,它就会向主进程请求更多的工作。主程序将更多的工作分配给从程序,程序继续运行

我编写程序的方式是,主进程使用MPI_Recv和MPI_ANY_源来接收从节点的工作

/* Allot some work to all the slaves (seed) */

while (istheremorework()) {
            /* Master receives slaves work*/

            MPI_Status status;            
            MPI_Recv(recvbuf, width + 1, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
            int slave = status.MPI_SOURCE;

            cout << "Master recieved data from slave " << slave << endl;
            /* store the data */    
            /* Master sends new work to the slave */
            int* sendbuf;
            /* populate sendbuf */
            MPI_Send(&sendbuf, 2, MPI_INT, slave, MSG_TAG_DATA, MPI_COMM_WORLD);
            /* update remaining work information */;
}
/*将一些工作分配给所有从属(种子)*/
while(istheremorework()){
/*主人接受奴隶的工作*/
MPI_状态;
MPI_Recv(recvbuf、宽度+1、MPI_双精度、MPI_任意源、MPI_任意标记、MPI_通信世界和状态);
int slave=status.MPI\u源;

cout在Waitany版本中,您必须为主进程上的每个工作进程初始化并维护一个
MPI\u请求
Request对象,MPI必须在
MPI\u Waitany()
调用中循环所有这些对象
,您只需处理消息队列中的下一条消息。我想MPI_Recv版本会更好


您可以尝试使用性能分析器。对于中小型应用程序,这种情况下可能不会有太大的性能差异。但是,在大型应用程序中,同时分配这么多请求对象被认为是一个坏主意。

在Waitany版本中,您必须初始化并维护
MPI\U请求
主进程上每个辅助进程的请求对象,MPI必须在
MPI_Waitany()
调用中循环所有这些对象。使用
MPI_Recv(MPI_ANY_SOURCE)
,您只需处理消息队列中的下一条消息。我怀疑MPI_Recv版本会更好


您可以尝试使用性能分析器。对于中小型,这种情况下可能不会有太大的性能差异。但是,在大型情况下,同时分配这么多请求对象被认为是一个坏主意。

在第二个版本中,定义了
MPI_Waitany
中的
请求
?似乎您在
MPI_Waitany
之前有
Irecv
,但您没有显示。@Shibli:是的。您是对的。在第二个版本中,
Irecv
就在那里。在将工作初始分配给从机之后,使用“Irecv”打开一个通道,让所有从机接收他们的工作,然后使用
MPI_Waitany
r另一个。如果我的理解不正确,请纠正我。在第二个版本中,在
MPI_Waitany
中定义了
request
?似乎你在
MPI_Waitany
之前有
Irecv
,但你没有显示。@Shibli:是的。你是对的。在第二个版本中,
Irecv
在那里。在最初的所有之后向从机分配工作,使用“Irecv”为所有从机打开接收工作的通道,并使用
MPI_Waitany
逐个消费。如果我的理解不正确,请纠正我。
/* Allot some work to all the slaves (seed) */

/* Open a channel with all the slaves to receive their work. */
for (int k = 1; k < i; k++) {
    MPI_Irecv(&recbuf[k], BUFFER_LENGTH, MPI_DOUBLE, k, MSG_TAG, MPI_COMM_WORLD, &requests[k - 1]);
    /* Each slave sends the results to master */
}

while (istheremorework()) {
            /* Master receives slaves work*/         

            MPI_Waitany(np-1, requests, &index, statuses); 
            /* Using index to decide which slave sent the result */ 

            cout << "Master received data from slave " << slave << endl;
            /* store the data */    
            /* Master sends new work to the slave */
            int* sendbuf;
            /* populate sendbuf */
            MPI_Send(&sendbuf, 2, MPI_INT, slave, MSG_TAG_DATA, MPI_COMM_WORLD);
            /* update remaining work information */;
}