总结了一下sink模型。 功能:
获取相关统计量销毁包1.状态转移图
2.声明了五个局部统计量
3.声明了五个全局统计量
4.SV
Stathandle bits_rcvd_stathandle Stathandle bitssec_rcvd_stathandle Stathandle pkts_rcvd_stathandle Stathandle pktssec_rcvd_stathandle Stathandle ete_delay_stathandle Stathandle bits_rcvd_gstathandle Stathandle bitssec_rcvd_gstathandle Stathandle pkts_rcvd_gstathandle Stathandle pktssec_rcvd_gstathandle Stathandle ete_delay_gstathandle5.TV
Packet* pkptr; double pk_size; double ete_delay;6.INIT入口代码
/* Initilaize the statistic handles to keep */ /* track of traffic sinked by this process. */ //注册局部统计量 bits_rcvd_stathandle = op_stat_reg ("Traffic Sink.Traffic Received (bits)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); bitssec_rcvd_stathandle = op_stat_reg ("Traffic Sink.Traffic Received (bits/sec)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); pkts_rcvd_stathandle = op_stat_reg ("Traffic Sink.Traffic Received (packets)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); pktssec_rcvd_stathandle = op_stat_reg ("Traffic Sink.Traffic Received (packets/sec)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); ete_delay_stathandle = op_stat_reg ("Traffic Sink.End-to-End Delay (seconds)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); //注册全局统计量 bits_rcvd_gstathandle = op_stat_reg ("Traffic Sink.Traffic Received (bits)", OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL); bitssec_rcvd_gstathandle = op_stat_reg ("Traffic Sink.Traffic Received (bits/sec)", OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL); pkts_rcvd_gstathandle = op_stat_reg ("Traffic Sink.Traffic Received (packets)", OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL); pktssec_rcvd_gstathandle = op_stat_reg ("Traffic Sink.Traffic Received (packets/sec)", OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL); ete_delay_gstathandle = op_stat_reg ("Traffic Sink.End-to-End Delay (seconds)", OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);注册统计量的目的是什么? 官方文档的解释是:
Statistic registration provides a mechanism for multiple processes to share a common output vector in which to record simulation metrics. By using registration to obtain access to the statistic, processes need only coordinate on the name of the statistic. This has the particular advantage of easily avoiding conflicts between models that are developed independently. This function returns a statistic handle, which is required to write new values to the statistic with the KPs op_stat_write() and op_stat_write_t().
我们可以在多个进程模型中注册同一个statistic在不同的进程模型中就都可以向一个statistic中写入仿真数据返回的句柄可以将值写入这个statistic7.DISCARD的出口代码
/* Obtain the incoming packet. */ pkptr = op_pk_get (op_intrpt_strm ()); //获取包指针,包指针中包含的信息很多 /* Caclulate metrics to be updated. */ pk_size = (double) op_pk_total_size_get (pkptr); //获取包的大小 ete_delay = op_sim_time () - op_pk_creation_time_get (pkptr); //获取包的延时 //以上的三个数据都是临时变量,每次在状态跳转后其值都不会保留。就跟函数体内声明的局部变量效果一样。 //对于红色的非强制状态来说,执行完出口代码后,会跳转回自身,跳转后所有的临时变量就不会保存。接着执行入口代码,这里没有。然后将控制权交给仿真核心。仿真核心将仿真时间推进到下一个仿真时间,即又一个包达到,产生中断。仿真核心将控制权交给红色的进程模型,进程模型执行出口代码。又一个循环。 /* Update local statistics. */ // 将(time,value)数值对写入统计量的句柄。很好奇,为什么不直接写入统计量,非要写入句柄。 op_stat_write (bits_rcvd_stathandle, pk_size); op_stat_write (pkts_rcvd_stathandle, 1.0); op_stat_write (ete_delay_stathandle, ete_delay); //每秒的比特数为什么跟收到的比特数都是一个值? op_stat_write (bitssec_rcvd_stathandle, pk_size); //这里是写入了两次数据,还是写完了马上清零? //当仿真核心推进了一个新的中断的产生,进程模型在响应中断的时候,仿真时间是不是不变???我感觉是不变的。如果不变的话,那就是马上清零了。 op_stat_write (bitssec_rcvd_stathandle, 0.0); //跟上面一样 op_stat_write (pktssec_rcvd_stathandle, 1.0); op_stat_write (pktssec_rcvd_stathandle, 0.0); /* Update global statistics. */ op_stat_write (bits_rcvd_gstathandle, pk_size); op_stat_write (pkts_rcvd_gstathandle, 1.0); op_stat_write (ete_delay_gstathandle, ete_delay); op_stat_write (bitssec_rcvd_gstathandle, pk_size); op_stat_write (bitssec_rcvd_gstathandle, 0.0); op_stat_write (pktssec_rcvd_gstathandle, 1.0); op_stat_write (pktssec_rcvd_gstathandle, 0.0); /* Destroy the received packet. */ op_pk_destroy (pkptr); //销毁包tags:opnet