c++ - 我可以捆绑两个 MPI 消息吗?

标签 c++ c cluster-computing mpi openmpi

我正在尝试乱序进行一对一通信。基本上我有多个相同大小的 float 组,由整数 id 标识。

每条消息应该如下所示:

<int id><float array data>

在接收方,它确切地知道有多少个数组,因此设置了准确的接收数。收到消息后,它会解析 id 并将数据放入正确的位置。问题是消息可以从任何其他进程发送到接收进程。 (例如,生产者有一个工作队列结构,并处理队列中可用的任何 id。)

由于 MPI 只保证 P2P 顺序传递,我不能简单地将整数 id 和 FP 数据放在两个消息中,否则接收方可能无法将 id 与数据匹配。 MPI 也不允许一次发送两种类型的数据。

我只能想到两种方法。

1) 接收方有一个大小为 m (source[m]) 的数组,m 是发送节点的数量。发件人先发送id,然后发送数据。接收方在收到来自发送方 i 的整数消息后将 id 保存到 source[i]。从发送者 i 接收到 FP 数组后,它检查 source[i],获取 id,并将数据移动到正确的位置。它之所以有效,是因为 MPI 保证了有序的 P2P 通信。它要求接收方为每个发送方保留状态信息。更糟糕的是,如果单个发送进程可以在数据之前发送两个 id(例如多线程),则该机制将不起作用。

2) 将 id 和 FP 视为字节,并将它们复制到发送缓冲区中。将它们作为 MPI_CHAR 发送,接收方将它们转换回整数和 FP 数组。然后我需要支付将东西复制到发送方字节缓冲区的额外费用。随着 MPI 进程中线程数量的增加,总临时缓冲区也会增加。

它们都不是完美的解决方案。我不想在进程中锁定任何东西。不知道大家有没有更好的建议。

编辑:代码将在带有 infiniband 的共享集群上运行。这些机器将被随机分配。所以我不认为 TCP 套接字能够在这里帮助我。另外,IPoIB 看起来很贵。我确实需要完整的 40Gbps 通信速度,并让 CPU 继续进行计算。

最佳答案

您可以在接收函数中指定 MPI_ANY_SOURCE 作为源排名,然后使用它们的标签对消息进行排序,这比创建自定义消息更容易。这是一个简化的示例:

#include <stdio.h>
#include "mpi.h"

int main() {
    MPI_Init(NULL,NULL);
    int rank=0;
    int size=1;
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    MPI_Comm_size(MPI_COMM_WORLD,&size);

    // Receiver is the last node for simplicity in the arrays
    if (rank == size-1) {
        // Receiver has size-1 slots
        float data[size-1];
        MPI_Request request[size-1];

        // Use tags to sort receives
        for (int tag=0;tag<size-1;++tag){
            printf("Receiver for id %d\n",tag);
            // Non-blocking receive
            MPI_Irecv(data+tag,1,MPI_FLOAT,
                      MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&request[tag]);
        }

        // Wait for all requests to complete
        printf("Waiting...\n");
        MPI_Waitall(size-1,request,MPI_STATUSES_IGNORE);
        for (size_t i=0;i<size-1;++i){
            printf("%f\n",data[i]);
        }
    } else {
        // Producer
        int id = rank;
        float data = rank;
        printf("Sending {%d}{%f}\n",id,data);
        MPI_Send(&data,1,MPI_FLOAT,size-1,id,MPI_COMM_WORLD);
    }

    return MPI_Finalize();
}

关于c++ - 我可以捆绑两个 MPI 消息吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12701393/

相关文章:

c++ - 输出不符合我的预期结果,如何解决?

c++ - 使用 #define 时奇怪的 mod 运算符 (%) 结果

c++ - 将 std::string 转换为 boost::posix_time::ptime

c - 尝试制作 irc 机器人

c - fwrite 一直在我的文件中写入不需要的文本

java - 具有多个实例的集群中的 JMS 持久订阅者

java - 集群中的spring boot应用程序

c++ - 让我难过的基本指针算术

c++ - clock_gettime() CUDA 的时间问题

hadoop - 我如何知道我的hadoop mapreduce应用程序是否以分布式模式运行