使用 NS3 和 std::thread 进行并行模拟

Posted

技术标签:

【中文标题】使用 NS3 和 std::thread 进行并行模拟【英文标题】:Parallel simulations using NS3 and std::thread 【发布时间】:2016-02-22 00:21:17 【问题描述】:

我正在使用 NS3 框架来运行具有各种配置的 Wi-Fi 模拟。我想使用 std::thread 在一个进程中同时运行许多(数百个)模拟。

这是我的代码,部分配置已编辑:

void simulation(RateAdaptation    rate_adaptation,
                const bool        channel_fading,
                // In meters, between AP and station.
                const uint32_t    distance)

  ns3::SeedManager::SetSeed(++seed);

  ns3::NodeContainer station_node, ap_node;
  station_node.Create(1);
  ap_node.Create(1);

  ns3::YansWifiChannelHelper channel;
  channel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
  channel.AddPropagationLoss( "ns3::LogDistancePropagationLossModel");



  // About 130 lines of more configuration for the simulation and
  // function parameters.



  ns3::Simulator::Stop(ns3::Seconds(10.0));

  ns3::Ptr<ns3::FlowMonitor> flowmon;
  ns3::FlowMonitorHelper *flowmonHelper = new ns3::FlowMonitorHelper();
  flowmon = flowmonHelper->InstallAll();

  ns3::Simulator::Run();
  ns3::Simulator::Destroy();
  flow_output(flowmon, flowmonHelper);


int main(int argc, char *argv[])

  std::vector<std::thread> jobs;

  for (uint32_t i = 0; i < 20; ++i)
  
    uint32_t varying_distance = 5*(i+1);

    jobs.push_back(std::thread(simulation,
                               RateAdaptation::Aarf,
                               false,
                               varying_distance));
  

  for (auto it = jobs.begin(); it < jobs.end(); ++it)
  
    it.join();
  

  return 0;

当我只为作业中的一项作业运行此代码时,它运行良好,但对于任何更大的数字(比如两个),我会得到如下输出:

assert failed. cond="SystemThread::Equals (m_main)", msg="Simulator::ScheduleDestroy Thread-unsafe invocation!", file=../src/core/model/default-simulator-impl.cc, line=289
terminate called without an active exception
Command ['[redacted]'] terminated with signal SIGIOT. Run it under a debugger to get more information (./waf --run <program> --comm    and-template="gdb --args %s <args>").

确实在 Valgrind 中运行它会返回数百个问题。

两个问题:

是否有可能我做错了什么,NS3 应该支持这一点? 已知 NS3 不能并行运行多个模拟吗?

【问题讨论】:

【参考方案1】:

简短的回答:你不能用 ns-3 做到这一点。

长答案:使用多个进程而不是多个线程(ns-3 库维护不受多线程并发保护的全局状态)。

我建议使用 ns-3 python 包装器来轻松设置并行多处理作业。如果您想在默认跟踪设置之外执行跟踪,这可能不是一件容易的事(在这种情况下,您可能需要在 C++ 中进行自己的跟踪并在 python 中进行拓扑设置)

【讨论】:

感谢您的回复!【参考方案2】:

我的解决方法是注释掉 default-simulator-impl.cc 中的 2 个断言检查,然后新线程运行良好:

DefaultSimulatorImpl::Schedule (Time const &delay, EventImpl *event)

// NS_ASSERT_MSG (SystemThread::Equals (m_main), "Simulator::Schedule Thread-unsafe invocation!"); // 第 231 行 ...

DefaultSimulatorImpl::ScheduleNow

// NS_ASSERT_MSG (SystemThread::Equals (m_main), "Simulator::ScheduleNow 线程不安全调用!"); // 第 284 行 ...

然后运行 ​​valgring 以验证潜在的种族/内存问题。

【讨论】:

它确实按预期工作。不过,我注意到子线程上的数据速率较低。因此,ns-3 似乎仍然给“主线程”更多的调度时间。 这是有史以来最糟糕的主意。 ns-3 不能在多线程环境中工作,除非您确保 所有 您的 ns-3 调用发生在 exact 同一个线程(调用 Simulator::Run 的那个) )。来自多个线程的多个 ns-3 调用最多会生成随机垃圾输出,因为在 ns-3 深处隐藏着共享状态和共享缓存。 为什么将其限制为单线程实现...我看到了 2009 年左右的与多线程相关的代码; groups.google.com/forum/#!searchin/ns-3-users/$20multithread/…

以上是关于使用 NS3 和 std::thread 进行并行模拟的主要内容,如果未能解决你的问题,请参考以下文章

C++ std::thread概念介绍

OpenMP、MPI、POSIX 线程、std::thread、boost::thread 如何关联?

Manning新书C++并行实战,592页pdf,C++ Concurrency in Action

C++ 并行编程《一》

相同值的并行写入

为啥 C++ 标准库中没有线程池?