C++ 将对象向量序列化为std::string以用于MPI

C++ 将对象向量序列化为std::string以用于MPI,c++,serialization,mpi,C++,Serialization,Mpi,我正在尝试通过MPI与大小不同的std::vector通信。MyClass包含未初始化或大小不同的向量成员。为此,我编写了一个serialize und deserialize函数,将这样的std::vector读写到std::string,然后通过MPI进行通信 class MyClass { ... int some_int_member; std::vector<float> some_vector_member; } std::vector<M

我正在尝试通过MPI与大小不同的std::vector通信。MyClass包含未初始化或大小不同的向量成员。为此,我编写了一个serialize und deserialize函数,将这样的std::vector读写到std::string,然后通过MPI进行通信

class MyClass {
    ...
    int some_int_member;
    std::vector<float> some_vector_member;
}

std::vector<MyClass> deserialize(const std::string &in) {
    std::istringstream iss(in);

    size_t total_size;
    iss.read(reinterpret_cast<char *>(&total_size), sizeof(total_size));

    std::vector<MyClass> out_vec;
    out_vec.resize(total_size);

    for(MyClass &d: out_vec) {
        size_t v_size;
        iss.read(reinterpret_cast<char *>(&d.some_int_member), sizeof(d.some_int_member));
        iss.read(reinterpret_cast<char *>(&v_size), sizeof(v_size));
        d.some_vector_member.resize(v_size);
        iss.read(reinterpret_cast<char *>(&d.some_vector_member[0]), v_size * sizeof(float));
    }

    return out_vec;
}


std::string serialize(std::vector<MyClass> &data) {
    std::ostringstream os;

    size_t total_size = data.size();
    os.write(reinterpret_cast<char *>(&total_size), sizeof(total_size));

    for(MyClass &d: data) {
        size_t v_size = d.some_vector_member.size();
        os.write(reinterpret_cast<char *>(&some_int_member), sizeof(some_int_member));
        os.write(reinterpret_cast<char *>(&v_size), sizeof(v_size));
        os.write(reinterpret_cast<char *>(&d.some_vector_member[0]), v_size * sizeof(float));
    }
    return os.str();
}
我的实现原则上是可行的,但有时并不总是如此!MPI进程在我认为与序列化相关的位置崩溃。发送的有效负载可以高达百兆字节。我怀疑使用std::string作为容器不是一个好的选择。使用std::string作为包含大量二进制数据的char[]的容器是否存在一些限制

请注意,我不想在使用boost::mpi及其序列化例程的同时使用它,也不想在我的项目中引入一个巨大的库(如谷物库)

一般来说,对二进制数据使用std::string是可以的,尽管有些人可能更喜欢C++17中的std::vector或std::vector,注意C++11字符串保证连续数据。代码中有两个重要的效率问题:

您始终拥有整个数据的三个副本。原始对象、序列化字符串和中间[io]字符串流。 您不能在ostringstream中预分配保留数据,这可能会导致过度分配和频繁重新分配。
因此,您浪费了大量内存,这可能导致错误分配。这就是说,它可能是完美的,你只是有一个内存泄漏的地方。如果不知道错误的原因和应用程序的性能分析,就无法判断这是否是一个实际问题

我不确定你想从答案中得到什么。这是关于车祸的吗?然后,我们需要您当前调试工作的详细信息和描述。或者这是关于如何正确地进行序列化?或者,这是如何用MPI序列化来发送复合C++对象的方法?如果这真的是通过MPI实现序列化数据的发送,那么至少我们需要查看您的MPI代码。这些问题中有很多都是关于意见的。请把问题集中在具体的目标和标准上。嗨,祖兰,很抱歉,这个问题不是很精确。我会试着重新措辞。我在一个大型数值模拟中使用上述例程,有时会崩溃,即使许多MPI请求没有问题。堆栈跟踪不是很有帮助,因为它包含坏的alloc,所以我想这是一些内存问题,我不容易创建一个最小的工作示例。我怀疑std::string的某些限制是问题所在,因此我的问题是,您可以尝试将序列化方法封装在try{…}catchstd::bad_alloc&{…}块中。此外,您还可以使用内存探查器来分析内存泄漏。虽然字符串可以工作,但MPI提供了自己的可移植方法,可以使用MPI_pack和MPI_Unpack序列化数据包数据。此外,您可能还需要研究Boost.MPI中序列化的实现。