【问题标题】:boost::mpi and boost::serialization errorsboost::mpi 和 boost::序列化错误
【发布时间】:2016-02-28 09:52:29
【问题描述】:

我使用 openmpi 和 linux mint, 考虑以下示例:

#include <boost/mpi.hpp>
#include <iostream>
#include <string>
#include <boost/serialization/string.hpp>

namespace mpi = boost::mpi;
using namespace std;

int main()
{
    mpi::environment env;
    mpi::communicator world;

    if (world.rank() == 0)
    {
        world.send(1, 0, std::string("3664010"));
        while (1)
        {
             world.send(1, 0, std::string("3664012"));
             sleep(1);
        }
     }
     else
     {
        std::string msg;
        string dst;
        bool first = true;

        while (1)
        {
            world.recv(0, 0, msg);
            if (first) {dst = msg;first = false;}
            std::cout << "slave received=" << dst << " msg=" << msg << std::endl;
        }
     }

    return 0;
}

编译:mpic++ -std=c++0x test.cc -lboost_serialization -lboost_mpi
运行:mpirun -np 2 ./a.out
输出: 从机收到=3664010 消息=3664010
从机收到=3664012 消息=3664012
从机收到=3664012 msg=3664012

只有在所有消息长度相等时才会重现错误。例如,如果第二条消息是“3664012andmore”,一切正常:
从机收到=3664010 消息=3664010
从机收到=3664010 msg=3664012andmore
从机收到=3664010 msg=3664012andmore
从机收到=3664010 msg=3664012andmore

看起来 dst 和 msg 使用相同的内存缓冲区。只有当字符串长度不同时,它们才会开始使用不同的内存缓冲区。我使用以下解决方法(msg = string()) 告诉编译器 msg 已更改:

std::cout << "slave received=" << dst << " msg=" << msg << std::endl;
msg = string();

而且效果很好。有没有更好的解决方案?谢谢。

【问题讨论】:

  • 我用 -O0 编译。字符更少,一切都很好。只有等长的问题
  • 你能用调试器检查dstmsg 是否真的为字符数组使用相同的内存?也许在serialization 中省略了写时复制?
  • 我输出了地址 (int*)dst.c_str() 和 (int*)msg.c_str()。他们是平等的
  • 那是一个错误,你应该报告它。
  • 我怀疑serialization 中存在问题,例如覆盖(写时复制)字符串的内存 - 尽管您必须自己单步执行序列化代码以检查mpi 是否没有'不要将Archive 专门用于序列化,否则编译器有问题,因为在 C++0x 和之后不应该有 COW 字符串...

标签: c++ openmpi boost-serialization boost-mpi


【解决方案1】:

使用不带字符串cow的gcc c++11解决了问题

【讨论】:

    猜你喜欢
    • 2014-06-07
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多