c++ - 将对象 vector 序列化为 std::string 以便与 MPI 一起使用

标签 c++ serialization mpi

我正在尝试传达 std::vector<MyClass>通过 MPI 具有不同的大小。 MyClass包含可能未初始化或大小不同的 vector 成员。为此,我写了一个 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 这样的大型库引入我的项目)

最佳答案

一般使用std::string对于二进制数据很好,尽管有些人可能更喜欢 std::vector<char> - 或 std::vector<std::byte>在 C++17 中( see also ,注意 C++11 字符串保证连续数据)。您的代码中存在两个显着的效率问题:

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

因此,您浪费了大量内存,这可能会导致 bad_alloc .也就是说,它可能完全没问题,只是某处有内存泄漏。在不知道 bad_alloc 的原因的情况下,无法判断这对您来说是否是一个实际问题。以及您的应用程序的性能分析。

关于c++ - 将对象 vector 序列化为 std::string 以便与 MPI 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44385538/

相关文章:

android - 仅在 Android 3.0 上异常(exception)

没有<iostream>的c++ nanopb Protobuff

time - 在科学集群上使用并行处理时 $time 意味着什么?

c - 从 MPI_Recv 接收到的标签存储在 MPI 中的哪里?

python - 多处理器环境下的 scikit-learn 网格搜索

c# - 为什么 C 和 C++ 中的 float / double 没有除余运算?

c++ - Visual Studio 中的 GCC 样式弱链接?

c++ - 奇怪的 GetWindowText();错误

c++ - 为什么 SSE 有 128 位加载功能?

c# - 无法将 JSON 数组反序列化为类型 - Json.NET