将 protobuf 与 MPI 一起用于新数据类型?

Using protobuf with MPI for new datatype?

通常,必须定义一个新类型并向 MPI 注册它才能使用它。我想知道是否使用 protobuf 序列化一个对象并使用 MPI 作为字节流发送它。我有两个问题: (1) 你预见到这种方法有什么问题吗? (2) 是否需要通过单独的MPI_Send()发送长度信息,还是可以探测并使用MPI_Get_count(&status, MPI_BYTE, &count)

例如:

        // sender 
        MyObj myobj; 
        ...
        size_t size = myobj.ByteSizeLong();
        void *buf = malloc(size);
        myobj.SerializePartialToArray(buf, size);
        MPI_Isend(buf, size, MPI_BYTE, ... )
        ...

        // receiver
        MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status);
        if (flag) {
            MPI_Get_count(&status, MPI_BYTE, &size);
            MPI_Recv(buf, size, MPI_BYTE, ... , &status);
            MyObject obj;
            obj.ParseFromArray(buf, size);
            ...

        }

通常你可以做到这一点。您的代码草图看起来也不错(接收方省略的 buf 分配除外)。正如 Gilles 指出的那样,确保对实际的 MPI_Recv 使用 status.MPI_SOURCEstatus.MPI_TAG,而不是 MPI_*_ANY.

但是,存在一些性能限制。

  1. Protobuf 不是很快,特别是由于 en-/decoding。这在很大程度上取决于您对性能的期望。如果您 运行 在高性能网络上,假设影响很大。这里是some basic benchmarks.

  2. 不知道前面的消息大小,因此总是在发送之后发布接收也对性能有影响。这意味着实际传输可能会稍后开始,这可能会或可能不会对发送方产生影响,因为您使用的是非阻塞发送。在某些情况下,您 运行 会遇到一些关于意外消息数量的实际限制。这不是一般的正确性问题,但可能需要一些配置调整。

如果您继续采用您的方法,请记住对实施进行一些性能分析。使用 MPI 感知性能分析工具确保您的方法不会引入关键瓶颈。