如果我误解了MPI_Send
和MPI_Recv
的工作方式,请纠正我,因为我刚刚开始学习MPI。
我目前的理解是,MPI标准保证从一个发送者到一个接收者一个接一个地发送的两个消息将始终以与发送者相同的顺序出现给接收者。这告诉我,某种排队必须在接收者或发送者身上发生,或作为某种分布状态的一部分发生。
我试图了解这个队列的性质,所以我编写了一个简单的pingpong
程序,其中所有奇数排名的节点将发送和接收节点号位于其下的偶数排序节点。 / p>
这个想法是,如果在集群中的所有节点之间共享一个全局队列,那么使用更多数量的节点运行应该会大大增加在每个节点上观察到的延迟。另一方面,如果队列位于每个接收器,则延迟增加应该相对较小。但是,我的结果非常复杂,所以我不确定如何解释它们。
有人可以提供以下结果的解释,关于队列驻留的位置吗?
$ mpirun -np 2 simple
Rank = 0, Message Length = 0, end - start = 0.000119
$ mpirun -np 2 simple
Rank = 0, Message Length = 0, end - start = 0.000117
$ mpirun -np 4 simple
Rank = 2, Message Length = 0, end - start = 0.000119
Rank = 0, Message Length = 0, end - start = 0.000253
$ mpirun -np 4 simple
Rank = 2, Message Length = 0, end - start = 0.000129
Rank = 0, Message Length = 0, end - start = 0.000303
$ mpirun -np 6 simple
Rank = 4, Message Length = 0, end - start = 0.000144
Rank = 2, Message Length = 0, end - start = 0.000122
Rank = 0, Message Length = 0, end - start = 0.000415
$ mpirun -np 8 simple
Rank = 4, Message Length = 0, end - start = 0.000119
Rank = 0, Message Length = 0, end - start = 0.000336
Rank = 2, Message Length = 0, end - start = 0.000323
Rank = 6, Message Length = 0, end - start = 0.000287
$ mpirun -np 10 simple
Rank = 2, Message Length = 0, end - start = 0.000127
Rank = 8, Message Length = 0, end - start = 0.000158
Rank = 0, Message Length = 0, end - start = 0.000281
Rank = 4, Message Length = 0, end - start = 0.000286
Rank = 6, Message Length = 0, end - start = 0.000278
这是实现乒乓球的代码。
#include "mpi.h" // MPI_I*
#include <stdlib.h>
#define MESSAGE_COUNT 100
int main(int argc, char* argv[]){
if (MPI_Init( &argc, &argv) != MPI_SUCCESS) {
std::cerr << "MPI Failed to Initialize" << std:: endl;
return 1;
}
int rank = 0, size = 0;
// Get processors ID within the communicator
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
size_t message_len = 0;
char* buf = new char[message_len];
MPI_Status status;
// Pingpong between even and odd machines
if (rank & 1) { // Odd ranked machine will just pong
for (int i = 0; i < MESSAGE_COUNT; i++) {
MPI_Recv(buf, (int) message_len, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
MPI_Send(buf, (int) message_len, MPI_CHAR, rank - 1, 0, MPI_COMM_WORLD);
}
}
else { // Even ranked machine will ping and time.
double start = MPI_Wtime();
for (int i = 0; i < MESSAGE_COUNT; i++) {
MPI_Send(buf, (int) message_len, MPI_CHAR, rank + 1, 0, MPI_COMM_WORLD);
MPI_Recv(buf, (int) message_len, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
}
double end = MPI_Wtime();
printf("Rank = %d, Message Length = %zu, end - start = %f\n", rank, message_len, end - start);
}
delete[] buf;
MPI_Finalize();
return 0;
}