User Tools

Site Tools


cookbook:measuring

Measuring performance

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.

Mean and coefficient of variation of inter-arrival times

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.

Mean utilization of a machine

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) ]|

Time averaged content of a buffer

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