omnet++:官方文档翻译总结(四)

学习翻译自:Adding Statistics Collection - OMNeT++ Technical Articles

Part 5 - Adding Statistics Collection

①展示收发包的数量

为了大致了解运行时每个节点收发包的数量,我们给module对应的class添加两个计数器:numSent、numReceived

class Txc14 : public cSimpleModule
{
    private:
        long numSent;
        long numReceived;
    protected:

它们需要在initialize()中设置为0并且用关键字WATCH加以监视,这样我们就可以在运行时监视其变化了。现在我们可以使用Find/inspect对象对话框来了解有多少包被不同的节点收发了。

打开方式见下边两张图,打开结果其实是一样的,都是一个 Find Objects对话框。

omnet++:官方文档翻译总结(四)omnet++:官方文档翻译总结(四)

 

 

omnet++:官方文档翻译总结(四)

 

 需要注意的是,在具体的仿真model中,几乎不可能得到完全相同的数字,我们唯一能确定的就是intuniform()正常工作了。但是实际中仿真,我们可以通过这种方式很快地了解到model中各个节点的状态。

这些信息在显示时放在module的icon之上。在display关键字中使用t=这个tag指明文本,我们唯一需要修正的是运行时显示出来的字符串。以下代码做了这项工作:

void Txc14 :: refreashDisplay() const
{
    char buf[40];
    sprintf(buf,"rcvd: %ld sent: %ld",numReceived,numSent);
    getDisplayString().setTagArg("t",0,buf);
}

结果就像下边这样:

omnet++:官方文档翻译总结(四)

 

 ②添加统计信息

之前的仿真Model中我们收集到了一些统计信息,我们可以对其进行一些操作。例如,你可能对消息到底目的地前经历的平均跳数比较感兴趣。

我们将在每个消息到达时,把它所经历的跳数记录到一个输出向量中(例如一系列的(time,value)对,并根据time进行排序)。我们也可以记录下每个节点的平均值、标准差、最小值、最大值并且在仿真结束时把它们写入文件中。然后我们就可以用OMNET++ IDE中的工具来分析这个文件。

例如,我们添加一个output vector对象(用来记录信息,最后把这个对象中的信息保存到Tictoc15-#0.vec中)和一个histogram对象(用于计算平均值等等)到class中:

class Txc15 : public cSimpleModule
{
    private:
        long numSent;
        long numReceived;
        cLongHistogram hopCountStats;
        cOutVector hopCountVector;
    protected:

每当一个消息到达目的节点时,我们更新统计信息。把下段代码加入handleMessage()中:

hopCountVector.record(hopcount);
hopCountStats.collect(hopcount);

hopCountVector.record()函数将数据写入Tictoc15-#0.vec中。对于大的仿真model和长时间运行之后,vec文件会变的很大。为了解决这种情况,我们可以在ini文件中特别指明开启/关闭vector,我们也可以指定仿真时间间隔(在时间间隔以外的数据记录将被丢弃)。

当开启了新的仿真过程时,已存在的Tictoc15-#0.vec/sca文件就被删除了。

数值数据(仿真过程中通过histogram对象收集到)只能在finish()函数中手动记录。finish()方法在仿真成功完成(即它不因错误而终止的时候)之后被调用。recordScalar()方法负责把数据写入到Tictoc15-#0.sca文件中。

void Txc15::finish()
{
    //该方法在OMNET++仿真结束时调用
    EV<<"Sent:     "<<numSent<<endl;
    EV<<"Received: "<<numReceived<<endl;
    EV<<"Hop count, min:    "<<hopCountStats.getMin()<<endl;
    EV<<"Hop count, max:    "<<hopCountStats.getMax()<<endl;
    EV<<"Hop count, mean:    "<<hopCountStats.getMean()<<endl;
    EV<<"Hop count, stddev:    "<<hopCountStats.getStddev()<<endl;

    recordScalar("#sent",numSent);
    recordScalar("#received",numReceived);
    hopCountStats.recordAs("hop count");
}

sca文件将被存储在result/子目录下。

我们也可以在仿真过程中显示出这些数据。为了实现这一目的,右击一个module,选择Open Details。在弹出的检查框中我们可以看到hopCountStatshopCountVector对象。我们也可以跟进一步查看这两个对象中记录的数据,在之前的检查框中右击这两个变量,点击Open Graphical View:

omnet++:官方文档翻译总结(四)

 

 omnet++:官方文档翻译总结(四)

 

 最开始的图像是空的,但是在用FastExpress模式下运行,就能得到用于展示的足够的数据。一段时间后,我们可以得到以下的图像:

omnet++:官方文档翻译总结(四)

 

 omnet++:官方文档翻译总结(四)

 

 当我们认为已经收集到了足够多的数据,我们可以停止仿真然后在线下分析结果文件(Tictoc15-#0.vecTictoc15-#0.sca)。我们需要从菜单中选择Simulate->Conclude Simulation或者点图标omnet++:官方文档翻译总结(四),这将调用finish()函数并把数据写入sca文件。

 

 ③不修改model完成数据统计

在之前,我们在我们的model中添加了数据统计的代码,不过在编写代码时,我们通常不知道用户需要哪些数据

omnet++:官方文档翻译总结(四)

上一篇:一步步学习数据结构和算法之快速排序效率分析及java实现


下一篇:线程中断之interrupt和stop方法