OPNET结构 (OPNET Architecture) --2

来源:互联网 发布:js cookie时间 编辑:程序博客网 时间:2024/06/10 03:00

进程域(Process Domain)

1.进程模型运行(Process Model Operation)
支持process model的module有限(因为诸如generator,transmitter,receivers等出于方便和功能的原因,已经被预定义了,只需编辑其属性即可)。两种module可以支持行为建模:processors和queues。这些模块提供了模块基本的行为能力和大部分物理资源。Queue还可以让用户定义内部的子队列(subqueues),以及如何管理这些subqueue的方法。但是由于它们的基本建模技术还是相同的,所以以下并不区分它们,方便起见,以下用QP来指代这些模块。

1.1进程环境(Process Environment)

1.1.1中断驱动执行(Interrupt-Driven Execution)
process由interrupt驱动。所以process的第一个操作就是判断interrupt的类型,进而解析interrupt的属性。进程在阻止(Blocked)和活动(Active)两个状态间循环,通过interrupt由blocked进入active,完成操作后回到blocked。

1.1.2动态进程(Dynamic Processes)
在仿真开始时,每个QP只有一个进程,这个进程是由仿真核(Simulation Kernel)创建的,称为根进程(root process)。往往一个root process就可以完成QP的功能,但是在一些情况下,为了增强模块性和降低设计复杂性,QP也采用multiple processes。process可以通过调用op_pro_create()创建新的processes,也就是所谓的dynamic processes。

1.1.2.1进程层次(Process hierarchy)
由上,显然process有层次之分,但是OPNET并不要求parent process必须在它所有的child processess全部终止后才能终止。所以这就会在层次上出现“洞”。但是这个是可以通过root process来处理的,详见后述。child process的attributes在被promote之后就可以一直提升到node level作为queue和processor的一部分。

1.1.2.2共享内存结构(Shared Memory Architecture)
有三种机制用来作为multiple processess下,各个process之间的通信方式:
a)QP level共享内存:
通过函数op_pro_modmem_install()和op_pro_modmem_access()访问。为了保证process间通信机制,各个process应当遵循shared memory的数据类型,这就要求process都要知道,因而shared memory的数据结构定义应当房子外部定义".h"文件中,并包含在每个process的header block中。shared memory一开始是没有的,是由process来决定什么时候分配以及分配多大,这些通过op_pro_modmem_access()来完成。内存的分配一般是通过op_prg_meme_alloc()来完成。
b)父子共享内存:
只有以父子关系联系在一起的process才能访问的私有共享内存。这种共享内存只能在child process由op_pro_create()产生时由op_prg_mem_alloc()分配,且不能被替换。通过op_pro_parmem_access()访问。通过op_pro_invoke()通知对方对共享内存的内容进行的修改和,以及对内容的检查。
c)参数内存(argument memory)
将内存地址作为op_pro_invoke()的参数传给别的进程用以通信,通过op_pro_argmem_access()来完成访问。与前两个不同的是,这部分内存不是永恒的。

1.1.2.3动态进程上的操作(Operations on Dynamic Processes)

1.1.2.4中断驱动(Interrupt Steering)
当interrupt到来时,Simulation Kernel必须决定哪个process被调用来处理这个interrupt。由于root process是interrupt的缺省接受者,所以一般用root process来完成对interrupt的解析,从而决定调用哪个process。

1.1.3本地进程资源(Local Process Resources)

1.1.3.1输入输出流(Input and Output Streams)
QP的input stream能够从外部源受到packet。有两个外部源:packet stream object和remote deliver。
当packet从input stream到达时,接收QP的一个process由于stream interrupt而被调用。这个process通过op_intrpt_strm()来获悉这个packet是从哪个stream里来的。Input stream通常用非负的整数作为标号(index)。process通过op_pk_get()和stream index来获得packets。通过op_strm_pksize()获悉仍然留在input stream中的packet的数量。
对于output stream来说,跟input stream类似,也有一些函数:op_pk_send(), op_pk_send_delayed(), op_pk_send_forced(), op_pk_send_quiet()。也是用非负整数用来作标号。
Input and Output Stream在stream accessing机制下会用到。如果我们用D表示目的地,用S表示源,那么这个packet转发的顺序应当是:
a)D调用op_strm_access(),要求S发包,要指明stream index。
b)然后,D处产生强行中断,D的进程被挂起等待S的响应。interrupt类型为access interrupt。S调用op_intrpt_strm()来决定从哪个output stream被要求。然后根据要求发包,为了避免再在D处产生中断,使用op_pk_send_quiet()来发包。S被阻止。
c)D重新获得控制权,继续执行。通过op_strm_pksize()和op_pk_get()来获取包及相关信息。

1.1.3.2输入统计和本地输出统计(Input Statistics and Local Output Statistics)
Inuput statistics是QP内部的一个部分,用来接收同一个node下别的modules发来的数值。他们通过统计线(statistics wires)来传输。目的module通过op_stat_local_read()来读取值,由于没有缓存,所以只能读取最新的值。
statistics的变化会在目的module处产生统计事件(statistics event),每个event都会在接收QP处产生一个统计中断(statistics interrupt)。process通过调用op_intrpt_stat()来决定受到了什么类型的中断。
local output statistics用来报告用户定义的各个QP专有的统计量。
local statistic可以通过probe来获得。也可以通过statistics wire连接到同一node下的其他QP上,在module之间传送statistics的更新。statistics的更新通过调用op_stat_write()和op_stat_write_t()来实现。一旦statistics更新了,所有的目的module都会受到相应的通知。
每个QP都可以有人以素含量的local output statistics,可以被所有存在于QP中的process共享。process必须声明要用的local output statistics。出于这个目的,Process Editor提供了edit local statistics操作。local output statistics可以是单个也可以是数组。
为了能够访问statistics从而更新它们,process必须获得对应statistics的句柄(handle)。op_stat_reg()允许process获得这个句柄。关于op_stat_reg()和op_stat_write(),可以参考Simulation Kernel手册。

1.1.3.3全局统计(Global Statistics)
Global Statistics和Local Statistics操作上都差不多,但是从名字上我们就可以看出他们所关注的东西是不同的。这里不详述。

1.1.3.4子队列(Subqueues)

1.1.3.5属性(Attribute)

1.2进程模型组成(Process Model Components)

1.2.1状态转移图(State Transition Diagrams)

1.2.1.1强制和非强制状态(Forced and Unforced States)
process在任意时刻只能处在一个状态下。process可以根据它收到的interrupt在状态之间转移。
每个状态的执行过程分为两个部分。进入执行(enter executives)和离开执行(exit executives),分别在进入和离开该状态的时候执行。
Proc定义了两种状态,称之为强制状态(forced states)和非强制状态(unforced states),分别用绿色和红色表示。
Unforced states允许在process在enter和exit之间暂停。一旦process执行完unforced states下的enter executives,就被block,并将控制权交还给调用它的其他process。如果这个process是被Simulation Kernel调用的,block就意味着这个event的结束。但是此时这个process依然被挂起,直到下一个新的调用产生使得它进入当前状态的exit executives。
Forced states是不允旬process等待的。所以一般它的exit executives是空白的。这是它与Unforced states的最大区别。

1.2.1.2初始状态(Initial States)
initial states是process被第一次调用时的起始位置。通过set initial state或make initial state来设置。
begin simulation interrupts是一种module attribute,用来完成对initial state的进入。通过module的begsim intrpt属性来选择。当然也可以不选择使用begin simulation interrupts而使用普通的interrupt(不推荐)。

1.2.1.3状态转移(Transitions)
对于状态转移的规定有四个组成部分:源状态、目的状态、条件表达式、执行表达式。可以这样解读:当处在源状态下,如果条件是真,则执行操作,并且转移到目的状态。
转移条件是布尔表达式。表达式可能是很多东西复杂东西的组合。所有支持条件表达式的计算都必须在exit executives的末尾执行,因为它们马上就要在后面的计算条件表达式的值时用刀。

1.2.2使用宏来定义复杂或循环表达式(Using Macros to Define Complex or Recurring Expressions)
几乎所有Proto-C的宏都是在header block中定义的。宏通常用来表示常数,状态转移条件,状态转移操作,和普通的操作。宏也可以在外部文件".h"中定义。然后通过在header block中用#include包含进来。宏的定义是#define。(跟C几乎一模一样)

1.2.3变量(Variables)
process可以利用三种不同的变量,分别称之为state variables, temporary variables, global variables

1.2.3.1变量组成(Variable Components)
a)名字
b)数据类型(详见参考文档)。定制数据类型也在header block中进行。typedef struct(跟C一样)。
c)

1.2.3.2变量操作(Operations on Varuables)
1.2.3.3状态变量(State Variables)
State Variables用来保持和积累信息(比如:统计)。
State Variables在state variable block中声明。
State Variables是持久的,他们一直都在保持它们的值,他们只能通过执行process中显式的赋值语句修改。
State Variables相对于各个process而言是私有的(private)。即使它们在同一个QP下,即使它们有着相同的名字。
State Variables没有自动的初始化,所以在initial state一定要有初始化state variable的语句。

1.2.3.4临时变量(Temporary Variables)
Temporary Variables和State Variables最大的区别就是持久性,如果一个variable不需要在两次调用之间保持不变,那么我们只需要使用Temporary variables,反之,我们则需要使用State Variables。
Temporary Variables在Temporary Variable Block中声明,也可以在那里初始化赋值。

1.2.3.5全局变量(Global Variables)
Global Variables为不同module下的多个process提供了在一个公用的地方存储信息的方法。
Global Variables在header block下声明,所有与这个变量相关的process都应当声明这个变量,但是他们中只能有,也必须有一个作为主声明(principle declaration),其他的都是外部声明(extern declaration),通过加"extern"实现。
Global Variables的初始化和Temporary variable相似,但是只能通过principle declaration赋值。

1.2.4进程模型属性(Process Model Attributes)
1.2.4.1模型属性(Model Attributes)
在Interfaces->Model Attributes中设定。也可以通过op_ima_obj_attr_set()来设定,但是一般这些属性在仿真过程中只是读取,而不做修改,所以只需要用op_ima_obj_attr_get()访问即可。

1.2.4.2进程属性(Process Attributes)
主要是关于Process Attributes Interface的(Interfaces->Process Interfaces)。用来设定(set)一些process的attributes,并且可以把这些attributes提升(promote)到更高层次的上去,也可以让那些与模型无关的属性相对于上层隐藏(hiden)起来。

1.2.5模块化计算(Modularizing Computations)
两种实现方法:动态进程和函数调用

1.2.5.1动态进程(Dynamic Processes)

1.2.5.2函数调用(Function Calls)

1.2.6调试功能(Diagnostic Capabilities)
OPNET有个调试器ODB。允许互动监控仿真过程和对象状态。ODB详见External Interfaces手册。

2.进程模型的开发方法(Process Model Development Methodology)

节点域(Node Domain)

1.模块定义(Module Definitions)
modules表示通信节点中产生、消耗、处理数据的部分。有以下几种类型:processors, queues, generators, receivers, transmitters

1.1处理器模块(Processor Modules)

1.2队列模块(Queue Modules)
Queue和Processor之间最主要的区别是:Queue还有一个附加资源,称之为子队列(subqueue)。subqueue大大地方便了缓存和管理数据包的收集。之后详述。
subqueue作为queue的一个object,以queue的attribute中compound attribute的形式体现。

1.3发送模块(Transmitter Modules)
有三种发送模块:point-to-point, bus, radio
transmitter从一个或者多个输入流中收集packet,然后把它们转发到相应通信链路上的channel中去。在某个给定的输入流收到的数据被发送到同一个标号的channel上去。每个channel都有自己的数据率。如果packet到的时候,相应的channel正在处理之前的packet,那么该packet将被自动放到一个buffer中排队等待,这个buffer是无尽的。Channels是transmitter的下属object。同样,也是作为一个compound attribute。
transmitter也有一些统计功能,可以通过statistics wire和statistics probe获取。

1.4接收模块(Receiver Modules)
也有三种接收模块,跟发送模块对应。其功能也和transmitter类似,但是方向上显然不同。

2.连接定义(Connection Definitions)
Connection表示一个node下各个module之间的通信路径和关联关系。有三种类型的connection: packet stream, statistic wires, logical associations。

2.1包流(packet streams)
Packet streams用来负责把一个数据包从源module发送到destination module去。stream方式传送有三种方法来通知destination module包到达:scheduled, forced, quiet。
scheduled是按调度原则产生interrupt;forced是立即发生;quiet是不产生任何interrupt。generator和receivers的output stream通过流的intrpt method属性来决定采用什么方法。
packet stream支持在packet从源module进入stream到从stream进入目的module这段时间内的延迟仿真。缺省值是0。

2.2统计线(statistic wires)
统计线传输关于源module的状态信息。每个module都有一组本地输出统计(local output statistics),他们的值会在仿真过程中适时地更新。他们作为了statistic wires的信息源。像Queue和Processor这样的module他们有一些由进程模型定义的统计数据,这些数据通过op_stat_write()来更新。还有一些module他们的statistics是有Simulation Kernel在适当的时候自动的更新的。每根statistics wire只能传输一个output statistics这个通过statistics wire的src stat属性确定。
Processor和queue modules也有一组输入统计(input statistics),作为statistics wire的目的端。进程模型通过调用op_stat_local_read()来访问当前的输入统计值。
要注意,output statistics可以作为多个statistics wire的源,同样input statistics也可以作为多个statistics wire的目的。
当statistics变化的时候,目的module将被一个statistic interrupt通知。interrupt发生的条件由statistic wire的属性控制,这个属性是statistic trggers。
在node model中,statistic wire一般有两种使用方法。第一种,用来动态监控其他部分的状态。第二种,用来发送信号通知别人自己的状态变换,称之为旗语(semaphores)。

2.3逻辑关联(Logical Associations)
Logical associations是一种特殊的连接,并不在模块间传输任何数据,它用来指明两个模块间的关系。目前,他们只能支持特定类型的transmitter和receiver,比如:point-to-point, bus。所以logical association也被称之为logical transceiver associations。每对transceiver只能代表节点和一个link相连。

3.节点模型接口(Node Model Interface)
跟Process model非常类似。

3.1节点模型属性(Node Model Attributes)

3.2节点属性接口和衍生节点模型(Node Attribute Interfaces and Derived Node Models)

3.4统计提升(Statistic Promotion)

4.队列建模(Modeling Queues)
队列有一些预定义的基模型,分为两类:动态队列(active queues)和被动队列(passive queues),具体的模型详见参考文献。

4.1子队列抽象和包编号(Abstract Subqueue and Packet Indices)

4.2实现优先级队列(Implementing Priority Queues)

4.3实现有限队列(Implementing Finite Queues)

5.分层协议建模(Modeling Layered Protocols)

6.共享资源建模(Modeling Shared Resources)