对象的序列化向量为STD :: String,以与MPI一起使用

Serializing vector of objects to std::string for use with MPI

本文关键字:MPI 以与 一起 String 向量 序列化 STD 对象      更新时间:2023-10-16

我正在尝试通过MPI传达具有不同大小的std::vector<MyClass>MyClass包含可能是非初始化或大小变化的向量的成员。为此,我编写了serialize() UND 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的hundrets一样大。我怀疑将std::string用作容器不是一个不错的选择。使用std::string作为char[]的容器是否存在一些限制,我可能会跑到这里?

(请注意,我不想使用boost::mpi及其序列化例程,我也不想将巨大的库(例如cereal(吸入我的项目(

通常,尽管有些人可能更喜欢std::vector<char>-或C 17中的std::vector<std::byte>,但使用std::string进行二进制数据(另请参见,请参见,请参阅,请参见,请参见C 11个字符串保证连续数据(。您的代码中有两个重要的效率问题:

  1. 您始终拥有整个数据的三个副本。原始对象,序列化的string和中间[io]stringstream
  2. 您不能在ostringstream中预先分配(储备(数据,这可能导致过度分配和频繁的重新分配。

因此,您浪费了大量的内存,这可能会导致bad_alloc。也就是说,这可能很好,您只是在某处有记忆泄漏。如果不知道bad_alloc的原因和应用程序的性能分析,这对您来说是否是一个实际问题。