C++ MPI_发送和MPI_接收的消息队列是全局的还是特定于每个目标?

C++ MPI_发送和MPI_接收的消息队列是全局的还是特定于每个目标?,c++,c,mpi,openmpi,C++,C,Mpi,Openmpi,如果我误解了MPI\u Send和MPI\u Recv的工作方式,请纠正我,因为我刚刚开始学习MPI 我目前的理解是,MPI标准保证从一个发送者到一个接收者一个接一个地发送的两条消息在接收者面前总是以它们发送的相同顺序出现。这对我来说意味着某种排队必须发生在接收方或发送方,或者作为某种分布式状态的一部分 我试图理解这个队列的性质,因此我编写了一个简单的pingpong程序,在该程序中,所有奇数排名的节点都将与节点号位于其下方的偶数排名的节点一起发送和接收 其思想是,如果集群中的所有节点都共享一个

如果我误解了
MPI\u Send
MPI\u Recv
的工作方式,请纠正我,因为我刚刚开始学习MPI

我目前的理解是,MPI标准保证从一个发送者到一个接收者一个接一个地发送的两条消息在接收者面前总是以它们发送的相同顺序出现。这对我来说意味着某种排队必须发生在接收方或发送方,或者作为某种分布式状态的一部分

我试图理解这个队列的性质,因此我编写了一个简单的
pingpong
程序,在该程序中,所有奇数排名的节点都将与节点号位于其下方的偶数排名的节点一起发送和接收

其思想是,如果集群中的所有节点都共享一个全局队列,那么使用更多节点运行应该会大大增加每个节点上观察到的延迟。另一方面,如果队列位于每个接收器,则延迟增加应该相对较小。然而,我得到的结果非常复杂,所以我不确定如何解释它们

有人能就队列驻留的位置提供以下结果的解释吗?

$ 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;
}
#包括“mpi.h”//mpi\I*
#包括
#定义消息\u计数100
int main(int argc,char*argv[]){
if(MPI_Init(&argc,&argv)!=MPI_成功){

std::cerr此类详细信息取决于MPI实现。您可以通过阅读MPI库的源代码(如果可用)来收集一些信息。MPI中没有全局队列本身,尽管不同的网络硬件通常使用某种队列。在MPI中,仅保证秩对秩排序,并且仅适用于sam中的消息e具有相同标记的通信器。请注意,
MPI_Init()
可能在不同级别的不同时间完成,因此在开始测量乒乓延迟之前,您应该插入对
MPI_Barrier
的调用。@hristoilev,谢谢。很高兴知道这一点。