上下文: 在我的程序中,主进程正在为从进程分配工作。一旦从属进程完成工作,它就会从主服务器请求更多工作。大师给奴隶分配更多的工作,程序还在继续。
我编写的程序方式是,主进程使用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 */;
}
这两种方法在性能方面是否相同?你认为使用一个优于另一个的任何显着优势吗?
答案 0 :(得分:2)
在Waitany版本中,您必须为主进程上的每个worker初始化并维护一个MPI_Request
请求对象,并且MPI必须在MPI_Waitany()
调用中循环遍历所有这些请求对象。使用MPI_Recv(MPI_ANY_SOURCE)
,您只需处理消息队列中的下一条消息。我怀疑MPI_Recv版本会更好。
您可以尝试使用性能分析器。对于中小规模,在这种情况下可能没有太大的性能差异。然而,在大规模的情况下,同时分配许多请求对象被认为是一个坏主意。