上会说到,ns-3 Default模式的仿真时间是虚拟时钟,事件发生时间自定义为5分钟(也可以是5毫秒,5纳秒等等),与现实时间无任何关联,只与函数(事件)运行的时间有关,一个事件结束,立即切换到下一个事件,同时更新当前仿真时间。而realtime模式就是为了将仿真时钟与实时时间统一起来,其实更为精确地说是将仿真时钟与墙上时钟时间同步。

在仿真运行前,需要将仿真模式设置为real-time,这需要设置全局变量SimulatorImplementationType:

  GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));

我们在事件列表中插入三个事件:

  Simulator::Schedule (Seconds (0.5), &event_1);Simulator::Schedule (Seconds (2.5), &event_2);Simulator::Schedule (Seconds (4.5), &event_3);Simulator::Stop (Seconds (10.0));//设置仿真结束时间为10秒Simulator::Run ();//开始运行Simulator::Destroy ();//仿真结束,销毁对象,释放内存

三个事件分别发生于0.5秒,2.5秒,4.5秒。运行程序,我们可以清楚感受到,首个事件真的是在run开始后0.5秒调用,那么ns-3是如何精确保证程序能够阻塞0.5秒才调用首个事件(函数)以及后续事件呢?

首先介绍两个概念:

unix时间:

UNIX时间 ,或称 POSIX时间 是 UNIX 或 类UNIX 系统使用的时间表示方式:从协调世界时 1970年1月1日0时0分0秒起至现在的总秒数,不考虑闰秒 。

协调世界时:

协调世界时,Universal Time Coordinated,又称世界统一时间、世界标准时间、国际协调时间协调世界时是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。

那么unix以及类unix系统中,所看到20XX年X月X日X时X分X秒,都是以unix时间计算得到,即以1970年1月1日0时0分0秒作为起始点,计算当前的年月日时分秒。

ns-3的同步功能定义在Wall-Clock-Synchronizer.h中,具体实现在Wall-Clock-Synchronizer.cc中。struct timeval这个结构体是Unix系统time.h定义一个存储时间的结构体,其结构如下:

struct timeval
{
__time_t tv_sec;        /* Seconds. */
__suseconds_t tv_usec;  /* Microseconds. */
}

它有两个变量,一个是tv_sec他表示秒数,另一个是tv_usec表示微妙,这两个的和就是一个时间量,可以理解为一个实数的整数部分和小数部分,只不过把他俩分成两个变量存储。通过:

  struct timeval tvNow;gettimeofday (&tvNow, NULL);

可以获取当前的unix时间。还有一个结构体timespe可以存储更高精度的时间(纳秒级):

typedef long time_t;
#ifndef _TIMESPEC
#define _TIMESPEC
struct timespec {
time_t tv_sec; // seconds
long tv_nsec; // and nanoseconds
};
#endif

在unix系统中(linux与macos)中是使用频率计时的,一个节拍的时间即是unix系统的最小时间单位,通过:

  struct timespec ts;clock_getres (CLOCK_REALTIME, &ts);m_jiffy = ts.tv_sec * NS_PER_SEC + ts.tv_nsec;

可以获取系统最小时间单位  m_jiffy,这也将是程序wait时所使用的时间单位。

m_realtimeOriginNano = GetRealtime ();

这行代码可以把仿真开始时(Simulator::Run ()调用时)的时间记录于变量m_realtimeOriginNano中,单位是纳秒。 GetRealtime ()是一个ns3定义的函数,它返回一个UNIX 时间,可以理解为此时距离1970年1月1日0时0分0秒的时间,假设为1625888416s117us,并将其转化为ns作为返回值。变量m_realtimeOriginNano就是仿真开始的实时时间,GetRealtime ()-m_realtimeOriginNano是就是GetNormalizedRealtime ()的方法,它可以计算实时相对时间。

uint64_t
WallClockSynchronizer::GetNormalizedRealtime (void)
{NS_LOG_FUNCTION (this);return GetRealtime () - m_realtimeOriginNano;
}

在仿真开始时,仿真时钟为0,那么仿真时间线的起点0与实时时间的起点m_realtimeOriginNano对齐,我们需要解决两条时间线同步,后续事件也能在正确的是时刻调用。

假设某一时刻需要调用下一个事件,它本该是仿真运行后的第15us调用,但是时间已经流逝了18us,说明该事件已经滞后于实时时间了,则此时无需等待,立即调用该事件。

假设下一个事件应该是仿真运行后的第25us调用,但是实时时间流逝了18us,则说明需要等待7us。仿真器调用函数WallClockSynchronizer::DoSynchronize来实现同步。进入该函数后,再次获取一个当前实时时间,假如是19us。

那么实际上只需要让进程等待6us。通过:

uint64_t numberJiffies = ns / m_jiffy;

可以计算出程序需要等待的节拍数,锁住进程,等待时间到达25us时的信号量解锁进程。时间一旦到达25us,解锁进程,立即调用下一个事件。

以上就是realtime模式下时间同步机制的全部介绍。

ns-3离散事件仿真之default与realtime(二)相关推荐

  1. python离散事件仿真库SimPy官方教程

    参考:SimPy Discrete event simulation for Python 建议先简单了解仿真原理:离散事件仿真原理DES 简单介绍 simpy的实现关键在于生成器的使用,通过例子说明 ...

  2. Python离散事件仿真入门【Simpy】

    离散事件仿真 (DES) 往往是专门产品的领域,例如 SIMUL8 和 MatLab/Simulink .然而,当我在 Python 中执行过去使用 MatLab 的分析时,我很想测试 Python ...

  3. 【待分类】用 SimPy 进行离散事件仿真(一)入门篇

    官网链接 SimPy is a process-based discrete-event simulation framework based on standard Python. 1. 概念理解 ...

  4. 什么是离散事件模拟(DES)

    DES(Discrete event simulation) 参考网址: https://www.ncbi.nlm.nih.gov/books/NBK293948/ https://whatis.te ...

  5. 离散事件模拟在游戏中的应用

    离散事件模拟(discrete event simulation),这个东西可能在游戏领域用得并不是很多,它是模拟仿真领域的一个仿真模型,用来模拟在时间轴上一系列离散事件后,整个系统的变化情况,这么说 ...

  6. sdut 2087 离散事件模拟-银行管理

    离散事件模拟-银行管理 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Description 现在 ...

  7. 离散事件模拟-银行管理

    离散事件模拟-银行管理 Description 现在银行已经很普遍,每个人总会去银行办理业务,一个好的银行是要考虑 平均逗留时间的,即: 在一定时间段内所有办理业务的人员逗留的时间的和/ 总的人数.逗 ...

  8. 关于“PFC离散元仿真核心技术与应用”你想要了解的都在这

    背景介绍: 目前,解决岩土类工程问题的主要研究手段有三大类,分别是理论分析.室内实验和数值模拟.其中,数值模拟因其便捷.高效以及可控性成为当今最为常用的研究方法.PFC离散元计算方法在岩体的动态.非线 ...

  9. 【PFC离散元仿真核心技术与应用】专题来了

    ①.该专题详细介绍PFC软件的计算控制.离散元数值试样的生成方法.接触模型选择.参数标定.模型边界条件施加方法.PFC3D与FLAC3D耦合.离散-连续耦合模拟分析.PFC与CFD耦合.流固耦合框架等 ...

最新文章

  1. Linux改变输出字体颜色,linux下 C编程改变输出字体颜色
  2. Bzoj4016/洛谷P2993 [FJOI2014] 最短路径树问题(最短路径问题+长链剖分/点分治)
  3. python绘制灰度图片直方图-python+opencv 灰度直方图及其二值化
  4. mysql双向复制(主主模式)
  5. Hyperledger Fabric 私有数据(3)交易流程
  6. 又拍网架构-又一个用到python的网站
  7. [天地君亲若追问 枉为知音百年羞]2008.06.07 晃荡在芳华
  8. css 字体加粗_HTML基础属性与CSS基础
  9. dubbo的端口地址和ip写在那_开源一款超实用的 Dubbo 测试工具,已用半年,感觉很有feel~...
  10. Linux disk 100% busy,谁造成的?
  11. Fluent NHibernate other example
  12. C/C++ 取整函数ceil(),floor(),向上取整,向下取整
  13. matlab多行注释
  14. 遗传算法的应用之函数优化和组合优化
  15. 阿里云访问控制简要说明
  16. 【循序渐进学运维】MySQL运维系列文章汇总
  17. 可编辑div在光标位置插入指定内容
  18. Android中设置字体居中,【Android】TextView中不同大小字体如何上下垂直居中?
  19. lisp一键室内标注_[AutoCAD][AutoLisp]根据图框自动匹配标注比例、文字大小、线性比例等信息 | 古意人...
  20. Java对象大小内幕浅析

热门文章

  1. 详解 Dijkstra迪杰斯特拉算法
  2. android系统华为彩蛋,【小智】打开安卓“隐藏关卡”—— Android系统彩蛋大揭秘...
  3. 华为:配置交换机console口验证
  4. clientX与offsetX、clientWidth与offsetWidth的区别
  5. “水果零售第二股”百果园上市首日市值近百亿
  6. java实现双向链表的增删改
  7. 人类思想史上的黄金时代
  8. 无法更新计算机的启动设置安装,“windows 无法更新计算机的启动配置。安装无法继续”这样解决...
  9. php上传进度条问题,php上传进度条
  10. 【电子购书商城】(二)Login登录功能的实现