cookbook:measuring

When executing a simulation experiment we are interested in performance indicators. To calculate these performance indicators we introduce seperate processes in which the calculation takes place. Such a process can be considered to be an oscilloscope. By instantiating a number of these processes we can calculate various performance indicators. The different processes are identified by their name.

We present a process that calculates the mean and the coefficient of variation of the inter-arrival time. We introduce a process for calculating the utilization of a machine. We give a process that calculates the time averaged content of a buffer. For an explanation of the used iterative formulas we refer to Learning chi1.0.

In models sometimes we are interested in the mean inter-arrival time and the coefficient of the inter-arrival time.
The following piece of code illustrates this.
We have generator `G`

:

proc G(chan a!: item, val ta: real) = |[ var u: -> real = exponential(ta), t: real , id: nat = 1 :: *( a!(id,time); t:= sample u; delay t; id:= id + 1 ) ]|

This generator sends every `sample u`

time units (assuming that `a!(id,time)`

is always possible) an item to another process, say exit process `X`

.
This process can be described by:

proc X(chan a?: item) = |[ var x: item :: * a?x ]|

We are interested in the inter-arrival time in process `X`

. For that purpose we modify process `X`

:

proc X(chan a?: item, p!: real) = |[ var x: item, t: real = 0.0 :: *( a?x; p!time - t; t:= time ) ]|

We determine the inter-arrival time in process `X`

. We send this value via channel `p`

to another process, say process `A`

. In process `A`

we calculate mean `m`

and variance `v`

. We introduce a parameter `n`

denoting that after receiving `n`

values the mean and the coefficient of variation are printed (By using the piping construction of Linux we also can send the result to a file). Coefficient of variation `c`

is defined by: `c = sqrt(v) / m`

. We have for process `A`

:

proc A(val title: string, chan p?: real, val n: nat) = |[ var i: nat = 0, m: real = 0.0, v: real = 0.0 , x: real :: *( p?x; i:= i + 1 ; ( i > 1 -> v:= (i - 2) / (i - 1) * v + (x - m)^2 / i | i <= 1 -> skip ) ; m:= (i - 1) / i * m + x / i ; ( i mod n > 0 -> skip | i mod n = 0 -> !! time, "\t", title, "\t", i , "\t", m, "\t", sqrt(v) / m, "\n" ) ) ]|

In variable `m`

we store the average value of the received `x`

-values, in variable `v`

we store the variance of the received `x`

-values. After `n`

receipts of variable `x`

we print the current time, the title of the process (to distinguish the various processes) the mean of `x`

and the coefficient of variation `c`

.

Eventually we combine the processes into process `S`

:

proc S() = |[ chan a: item, b: real :: G(a) || X(a,b) || A("mc",b,100) ]|

This process calculates the mean and the coefficient of variation of the inter-arrival times in process `X`

(or the inter-departure times in process `G`

). These values are printed after the reception of 100 items in process `X`

.

We define machine `M`

. The machine processes items with two processing times of 1.0 and 5.0 time units. The time is determined by a distribution. We assume a `bernoulli`

distribution with a probability of 0.5. This implies that 50% of the items have a processing time of 1.0 time units and 50% of the items have a procesing time of 5.0 time units.
The specification of process `M`

is:

proc M(chan a?,b!: item) = |[ var u: -> bool = bernouilli(0.5) , x: item, p: bool :: *( a?x; p:= sample u ; ( p -> delay 1.0 | not p -> delay 5.0 ) ; b!x ) ]|

We are interested in the mean utilization of the machine. For that purpose we modify machine `M`

. After receiving an item we send a message `false`

to an oscilloscope. Later we define this oscilloscope. After sending an item we send the message `true`

to the oscilloscope:

proc M(chan a?,b!: item, p!: bool) = |[ var u: -> bool = bernouilli(0.5) , x: item, pr: bool :: *( a?x; p!false; pr:= sample u ; ( pr -> delay 1.0 | not pr -> delay 5.0 ) ; b!x; p!true ) ]|

We introduce oscilloscope `U`

:

proc U(val title: string, chan p?: bool, val n: nat) = |[ var i: nat = 0, oldt: real = 0.0, u: real :: *( p?b; i:= i + 1 ; ( b -> u:= oldt / time * u | not b -> u:= oldt / time * u + (time - oldt) / time ) ; oldt:= time ; ( i mod n > 0 -> skip | i mod n = 0 -> !! time, "\t", title, "\t", i , "\t", u, "\n" ) ) ]|

We define process `MU`

consisting of machine `M`

and oscilloscope `U`

:

proc MU(var title: string, chan a?,b!; item, val n: nat) = |[ chan p: bool :: M(a,b,p) || U(title,p,n) ]|

We define an item:

type item = ?

We define generator `G`

. The generator produces items, according to an exponential distribution with an averaged inter arrival time of 2.0 time units. These items are sent to buffer process `B`

.

proc G(chan a!: item) = |[ var i: nat = 1, u: -> real = exponential(2.0), t: real :: *( a!(i,time); t:= sample u; delay t; i:= i + 1 ) ]|

The buffer process is modeled by:

proc B(chan a?,b!: item) = |[ var xs: [item] = [], x: item :: *( a?x; xs:+ xs ++ [ x ] | len(xs) > 0 -> b!hd(xs); xs:= tl(xs) ) ]|

A machine processes the items. We assume an exponential distributed processing time of 1.5 time units.
We define machine `M`

by:

proc M(chan a?,b!: item) = |[ var u: -> real = exponential(1.5), t: real, x: item :: *( a?x; t:= sample u; delay t; b!x ) ]|

Items leave the system via process `E`

, the exit process:

proc E(chan a?: item) = |[ x: item :: * a?x ]|

We are interested in the timed average content in the buffer. For that purpose we modify buffer `B`

.
After receiving or sending an item we send the length of list `xs`

to an oscilloscope. Buffer `B`

becomes:

proc B(chan a?,b!: item, c!: nat) = |[ var xs: [item] = [], x: item :: *( ( a?x; xs:= xs ++ [ x ] | len(xs) > 0 -> b!hd(xs); xs:= tl(xs) ) ; c!len(xs) ) ]|

If the length of the list in the buffer has been changed we notify the oscilloscope.
We introduce oscilloscope `V`

:

proc V(val title: string, chan p?: nat, val n: nat) = |[ var i: nat = 0, oldt: real = 0.0 , wmax: nat = 0, wold: real = 0.0, w,wav: real :: *( p?w; i:= i + 1 ; ( w <= wmax -> skip | w > wmax -> wmax:= w ) ; wav:= told / time * wav + (time - told) / time * wav ; oldt:= time ; ( i mod n > 0 -> skip | i mod n = 0 -> !! time, "\t", title, "\t", i, "\t", wmax , "\t", w, "\t", wav, "\n" ) ) ]|

We define process `BV`

consisting of buffer `B`

and oscilloscope `V`

:

proc BV(var title: string, chan a?,b!; item, val n: nat) = |[ chan p: nat :: M(a,b,p) || V(title,p,n) ]|

cookbook/measuring.txt · Last modified: Thursday, 12 February 2009 : 09:49:47 by hvrooy

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Noncommercial-Share Alike 4.0 International