使用 NS3 和 std::thread 的并行模拟
Parallel simulations using NS3 and std::thread
我正在使用 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 中解决了 returns 数百个问题。
两个问题:
- 会不会是我哪里做错了,NS3应该支持?
- 是否知道 NS3 不能运行并行进行多个模拟?
简短的回答:你不能用 ns-3 做到这一点。
长答案:使用多进程而不是多线程(ns-3 库维护不受多线程并发保护的全局状态)。
我建议使用 ns-3 python 包装器轻松设置并行多处理作业。如果您想在默认跟踪设置之外执行跟踪,这可能不是完全微不足道的(在这种情况下,您可能需要在 C++ 中进行自己的跟踪并在 python 中进行拓扑设置)
我的解决方法是注释掉 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 Thread-unsafe invocation!"); // 第 284 行
...
}
然后 运行 使用 valgring 验证潜在的 race/mem 问题。
我正在使用 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 中解决了 returns 数百个问题。
两个问题:
- 会不会是我哪里做错了,NS3应该支持?
- 是否知道 NS3 不能运行并行进行多个模拟?
简短的回答:你不能用 ns-3 做到这一点。
长答案:使用多进程而不是多线程(ns-3 库维护不受多线程并发保护的全局状态)。
我建议使用 ns-3 python 包装器轻松设置并行多处理作业。如果您想在默认跟踪设置之外执行跟踪,这可能不是完全微不足道的(在这种情况下,您可能需要在 C++ 中进行自己的跟踪并在 python 中进行拓扑设置)
我的解决方法是注释掉 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 Thread-unsafe invocation!"); // 第 284 行 ... }
然后 运行 使用 valgring 验证潜在的 race/mem 问题。