这是 ICC 09 上的一篇文章( ICC 什么时候也接受这样的文章啦?),对最近被使用的一些网络仿真器进行了介绍,并对其性能进行了比较。正好所介绍的网络仿真器除了 JIST 以外,其他的都使用过,基本上还是比较认同作者的比较结论的。原文章可以从 http://ds.informatik.rwth-aachen.de/publications/2009/ 上下载到,文章标题为:“A performance comparison of recent network simulators ”。下面是阅读此文章后的一些笔记。
网络仿真器在网络协议的研究中还是占有着重要的地位,特别是在网络比较复杂、参数多变的情况下。现在大部分已有的网络仿真器都是基于离散事件仿真( DES )的。也就是说,网络节点触发事件,同时仿真器维护着一个事件列表。现在用的最多的网络仿真平台是 NS2 ,实际上这也是学术界网络仿真事实上的标准。但是实际上 NS2 却在仿真时间和使用内存上有着扩展性不足的问题,特别是对于现在的新型网络,如无线传感器网络、 P2P 网络以及网格网络等,因为这些网络的仿真可能需要大量的节点。为此,也有一些针对 NS2 的改进,如并行处理。尽管如此,现在 NS2 还是在做着一次大的重新设计。这就是 NS3 ,对仿真性能进行了改进。
除了 NS2 之外,学术界和工业界也提出了多种仿真器。杰出的代表包括 OMNeT++ 、基于 Java 的 JiST 以及商业上使用的 OPNet 等。另外,还有一些专门针对某个领域的网络仿真器,如针对 WSN 的 TOSSIM 。这就给研究者带来了一个问题,该使用什么样的网络仿真器,达到高的仿真性能呢?这篇文章主要是对 NS2 、 NS3 、 OMNeT++ 、 JiST 、 SimPy 进行了性能比较。因为 NS3 、 OMNeT++ 和 JiST 已经得到了越来越多的研究者关注,而 SimPy 则代表了一种新的基于进程范式的仿真器设计(使用 Python 语言实现)。
1.NS2
NS2 采用了 C++ 来实现仿真节点的行为,而 oTCL 脚本来控制仿真过程。这种设计在当初是合适的,可以减少重编译过程而加快仿真,因为 C++ 程序的重编译过程确实是一个耗时的过程。尽管如此,从现代的观点看,这种折衷在关注可扩展网络仿真的时候是否合适还是一个问题。
2.NS3
和 NS2 一样, NS3 还是采用了 C++ 语言来实现仿真节点,但是却废弃了 oTcl 来控制仿真过程。取而代之的是,仿真过程可以通过纯的 C++ 代码实现,部分还可以使用 Python 语音。更多的, NS3 集成了 GTNetS 的架构设计概念和代码,而 GTNetS 被认为具有很好的可扩展性。这样设计的同时也带来了很大的兼容性问题。事实上, NS2 的模块移植到 NS3 上都需要手工的移植过程。除了性能的改进外, NS3 还支持和物理实现的集成,如 BSD Socket 或者 POSIX 线程等。
3.OMNeT++
事实上, OMNeT++ 都不是一个网络仿真器,而只是一个通用的离散仿真框架。通过 INET 包, OMNeT++ 提供了对网络建模的能力。另外, MF 和 Castalia 模块提供了对移动 Adhoc 和无线传感器网络的仿真功能。
OMNeT++ 在简单模块中实现基本的协议行为,然后通过组合这些简单模块成复合模块而成为仿真节点, OMNeT++ 中的网络仿真就是这些复合模块的组合。 OMNeT++ 也是采用 C++ 来实现的。但是使用了一种网络描述语言 NED 来描述网络框架。通过更改 NED 描述文件即可改变 OMNeT++ 的仿真行为,例如可以更改网路中节点的数量,在这种情况下,网络节点的实现模块是在仿真执行过程中动态生成的。这个功能是仿真器严格的面向对象设计的一个结果。另外, OMNeT++ 还有一个可视化环境,可以方便初学者入门。
4.JiST
一个新的网络仿真器是 JiST ,从名字可看到是采用 Java 来实现的。它经常和 SWANS 一起使用,这是一个基于 JiST 的移动 Adhoc 网络仿真器。
JiST 通过表征网络元素的实体组成,这些实体在仿真的过程中通知仿真核心。由于一个实体中的代码就是一个 Java 程序,只有实体之间的交互才涉及到仿真时间。这种设计方式可以使得不同的实体之间并行执行,从而提高仿真性能。遗憾的是, JiST 项目已经停止而且不再维护。尽管如此, Ulm 大学还是发布了 JiST 的一些改进。
5.SimPy
SimPy 是一种基于进程范式的网络仿真器。不像其他的网络仿真器, SimPy 并没有一个公开可用的网络模块包。实际上,这只是一个使用 Python 的仿真 API 。在 SimPy 中,仿真的基本实体是进程。它们并行运行,并可以交互。大多数进程都是一个无限循环,里面包含着进程的行为。除了这些之外, SimPy 还提供了进程之间的同步以及对仿真数据的监控。
文中采用了一种简单的方式来测试仿真器的性能。在多个节点之间传递数据,并且具有着一定的丢包概率。通过对各种丢包概率和不同节点数量的报文丢失数来看,各个仿真器最后的结果基本上是相同的。另外,通过节点的多少来查看仿真器的可扩展性,通过丢包率的变化来查看内存的使用。
A. 仿真时间
对于不同的节点数量,当节点数目很大的时候, SimPy 明显占用很长的时间,几乎是 JiST 的 14 倍。 JiST(86s) 、 OMNeT++ 、 NS3 三者的时间差不多, NS2 的时间要多于这三者, SimPy(1225s) 要的时间是最多的。
对于不同的丢包率,所有的仿真器在丢包率增大的时候仿真时间都会减小。还有一点可以注意到,在丢包率较小的时候, SimPy 的仿真时间明显变长,从这里也可以得到一个结论,那就是 SimPy 的事件处理吞吐量是不如其他仿真器的。
B. 内存占用
对于不同的节点数量, JiST 比其他四个仿真器需要的内存更多。
对于不同的丢包率,当丢包率增大到 0.5 的时候,内存占用变化并不大。这也是一个仿真运行需要的内存。如 JiST 需要有 Java 虚拟机, SimPy 需要 Python 来执行。另外, SimPy 在丢包率较大的时候内存占用明显较大,而 JiST 在丢包率比较小的时候内存占用明显较大。(另外,在相关工作中,有研究者对比 JiST 和 NS2 在移动 Adhoc 环境下的性能,发现 NS2 明显比 JiST 占用更多的内存。这里作者的解释是在 NS2 中,当报文广播给另一个节点的时候, Radio 模块对报文在内存中做了多次复制。)
可以看到,各个仿真器都有着自己的不同特性,在选择网络仿真平台的时候还是需要根据自己的需求来选择合适的网络仿真软件。