MPI_Waitany()或MPI_Recv()与MPI_ANY_SOURCE?

时间:2017-05-22 00:16:37

标签: mpi hpc

上下文: 在我的程序中,主进程正在为从进程分配工作。一旦从属进程完成工作,它就会从主服务器请求更多工作。大师给奴隶分配更多的工作,程序还在继续。

我编写的程序方式是,主进程使用MPI_Recv和MPI_ANY_SOURCE从从属节点接收工作。

/* 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 */;
}

这部分代码也可以改写为

/* 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 */;
}

这两种方法在性能方面是否相同?你认为使用一个优于另一个的任何显着优势吗?

1 个答案:

答案 0 :(得分:2)

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

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