将对象的矢量序列化为std :: string以与MPI一起使用

时间:2017-06-06 08:53:29

标签: c++ serialization mpi

我正试图通过MPI传达不同大小的std::vector<MyClass>MyClass包含的成员可能是未初始化或大小不同的向量。为此,我编写了一个serialize()deserialize()函数,用于读取和写入std::vector<MyClass>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进程在我认为与序列化相关的位置崩溃。发送的有效负载可以与MB的数据库一样大。我怀疑使用std::string作为容器不是一个好选择。使用std::string作为char[]的容器是否存在一些限制,我可能会遇到大量二进制数据?

(注意,我不想使用boost::mpi及其序列化例程,我也不想将cereal等大型库引入我的项目中

1 个答案:

答案 0 :(得分:1)

通常情况下,使用std::string表示二进制数据是可以的,尽管有些人可能更喜欢{+ 1}} - 或{CES 17中的std::vector<char> see also,请注意C ++ 11字符串保证连续数据)。您的代码中存在两个显着的效率问题:

  1. 您始终拥有整个数据的三个副本。原始对象,序列化std::vector<std::byte>和中间string
  2. 您无法在[io]stringstream中预分配(保留)数据,这可能会导致过度分配和频繁重新分配。
  3. 因此,您浪费了大量内存,这可能会导致ostringstream。也就是说,它可能非常好,你只是在某个地方有内存泄漏。在不知道bad_alloc的原因和应用程序性能分析的情况下,无法判断这是否是一个实际问题。