Upload
susane
View
60
Download
1
Embed Size (px)
DESCRIPTION
Mesquite Corporation. INTRODUCTION TO CSIM 19 FOR C++ PROGRAMMERS. http://www.mesquite.com/documentation/index.htm#startcpp. What is CSIM?. Simulation language developed by Mesquite Software in Austin, TX C/C++ based Has now a Java-based version - PowerPoint PPT Presentation
Citation preview
INTRODUCTION TO CSIM 19 FOR C++ PROGRAMMERS
Mesquite Corporation
http://www.mesquite.com/documentation/index.htm#startcpp
What is CSIM? Simulation language developed by
Mesquite Software in Austin, TX C/C++ based
Has now a Java-based version Allows user to create process-
oriented, discrete-event simulation models
Implemented as a library No need to learn a new language
OUR FIRST CSIM PROGRAM
A very simple example (I) M/M/1 server with a FCFS queue Input parameters are
Time intervals between arrivals Service times
Server
A very simple example (II) We want to know
Average customer response time:time of arrival to time of departure
Customer throughput rate:customers served per unit time
Server utilization:Fraction of elapsed time the server is busy
Average queue length:number of customers at the facility
The sim process
#include <cpp.h> // CSIM C++ header filefacility *f; // the service center
extern "C" void sim() { // sim process create("sim"); // make this a processf = new facility("f"); // create service center fwhile (simtime() < 5000.0) { hold(exponential(1.0)); // delay
customer(); // generate new customer} // while loopreport(); // output results
}// sim
The customer process
void customer() {create("customer"); // make this a processf->use(exponential(0.5)); // get service
} // customer
Advantages of the approach
• We can describe system through actions taken by each customer
• Facility f manages its own queue
Output
CSIM Simulation Report (Version 19 for MSVC++) Mon May 13 13:42:39 1996
Ending simulation time:10001.909 Elapsed simulation time:10001.909CPU time used (seconds):0.490 FACILITY SUMMARYfacility service service queue response complname disc time util through-put length time countf fcfs 1.00954 0.512 0.506801. 019832.01229 5069
This is the default output.We can request much more specific data
Program analysis: processes Two processes
sim: the main process customer: describes customer
behavior A CSIM process is a C++ function which
executes the "create" statement Establishes the procedure as an
independent, ready-to-run process, Returns control to the calling process
Program analysis: facilities One facility
f: the service center A facility is
Declared with a “facility" declaration Initialized by the "facility()" function
To request service from a facility f, process can call “f->use(Delta_t)”where “Delta_t” is the request duration
Program analysis: simtime() A global “clock” variable keeps track of
the simulated time Double-precision floating point
variable Value can be accessed through
“simtime()” function
Program analysis: hold() “hold()” function causes time to pass for
the process that calls it Deals with simulated time Do not use “sleep()”
Program analysis: exponential() “exponential(Delta_t)” function returns
a value for a exponential random variable with mean “Delta_t” Many other functions of this type
CSIM PROCESSES
Processes Model the active elements of a system Created through a call to “create()” Can have multiple instances of the
same process:
while (simtime() < 5000.0) { hold(exponential(1.0)); // delaycustomer(); // generate new customer
} // while
Process attributes Each instance of a CSIM process has:
Its own internal state A unique process id A process priority One of the following external states:
Executing Waiting-to-execute Holding (for some time interval) Waiting (for some event to occur)
Warning CSIM processes look very much like
conventional OS processes They are different:
One OS process per CSIM simulation CSIM processes run within that
process CSIM processes use simulated time
Not physical time
CSIM process creation When a function calls create()
CSIM creates a process control block (pcb) for the new process and puts it on the “next event list”
Control is returned immediately to the process which invoked the function
CSIM process scheduling Non-preemptive
A new process will execute only after the currently running process leaves the running state by
Executing a hold() Going through a wait Terminating
CSIM FACILITIES
Facilities We can define
Single server facilities:Can service one process at a time
Multi-server facilities:Can service several processes at a time and have a single queue
Arrays of single server facilities:each with its own queue
Facility scheduling By default, a facility services processes
in priority order Where several processes have the same
priority, they will be served on FCFS basis
Other service disciplines can be specified
Example:single-server facility (I)
facility *ss; // declare facility...ss = new facility("sngle srvr");
// initialize ...ss->use(Delta_t);
// use ss for duration Delta_t
Example:single-server facility (II)
s->reserve(); // reserve facility...hold(Delta_t);...s->release(); // release facility...
Using a reserve/release pair lets us keepseparate counts of time spent by customers(a) in queue and (b) being serviced
Example:facility with three servers All three servers share the same queue
const long NSERV = 3; // 3 servers...facility_ms *ms; // declare facilityms = new facility_ms("multi", NSERV);...ms->use(service_time);....
The post office problem revisited (I)
#include <cpp.h> // CSIM C++ header filefacility_ms *po; // the service center
extern "C" void sim() { // sim process create("sim"); // make it a processpo = new facility_ms(“po“, 2); // create powhile (simtime() < 5000.0) { hold(exponential(1.0)); // delay
customer(); // generate new customer} // while loopreport(); // output results
}// sim
The post office problem revisited (II)
void customer() {create("customer"); // make it a processpo->use(exponential(0.5)); // get service
} // customer
Example:array of single-server facilities Each facility now has its own queue
const long NFACS = 10;facility_set *fa; // declare array fa = new facility_set("facs", NFACS);...i = random(0, NFACS - 1); // pick one (*fa)[i].use(service_time);//use facility[i]
Note the (*fa)[i]. without “->”
Example:setting a maximum wait time
const double MAXWAIT = 5.0;
...
st = ss->timed_reserve(MAXWAIT);
if (st < MAXWAIT) { // success
hold(service_time); ss->release(); // done
} else { //request timed out
...
}
Example:allowing preemption
FACILITY cpu; // declare facility cpu
cpu = new facility("cpu");
// initialize facility
...
cpu->set_servicefunc(pre_res)
// set service protocol to preempt-resume
...
priority = 100; // raise process priority
cpu->use(service_time);
CSIM STORAGES
Storages Like facilities but designed to be shared
Each process gets some units of storage
Used to simulate main memory Must have a name
Only used to label report entries
Example: single storage
const long SIZE = 100; storage *mem; // declare storagemem = new storage("mem", SIZE); // initialize mem with 100 units...amt = random(1, SIZE); mem->allocate(amt); // get storage ...mem->deallocate(amt); // release it...
Example: storage arrayconst long NSTORES = 5;const long SIZE = 100;storage _set *mems; // declare array...mems = new storage_set("mem", SIZE,
NSTORES); //initialize...(*mems)[3].allocate(amt); ...(*mems)[3].deallocate(amt);
Example:setting a maximum wait time
const double MAXWAIT = 1.0;st = mem->timed_allocate(amt, MAXWAIT);// maximum wait is one time unitif (st < MAXWAIT) {
// success...mem->deallocate(amt); // release
} else {// failure...
}
More options Can also specify faculties and storages
that can only be allocated at regular points in time Clock ticks
Must invoke “synchronous()” method before invoking “allocate()” method “synchronous()” method specifies
phase and period of allocation policy
CSIM BUFFERS
Buffers A buffer consist of
a counter indicating the amount of available capacity
A queue for processes waiting to get some buffer space
A typical producer behavior A queue for processes waiting to
free some buffer space A typical consumer behavior
Example:creating and accessing a buffer
const long SIZE = 100;
buffer *buf;
buff = new buffer("buff", SIZE);
...
amt = random(1, SIZE);
buff->get(amt);
...
buff->put(amt);
Example:setting a maximum wait time
st = buff->timed_get(amt, 1.0);
if (st < TIMED_OUT) {
// success
...
buff->put(amt);
} else {
// failure
...
}
CSIM EVENTS
Events Used to synchronize and control
interactions between different processes Have two states
Occurred (OCC) Not occurred (NOT_OCC).
Processes and events
A process can Set an event:
mark it as occurred Wait for an event:
when event occurs all waiting processes can continue occurred state
Queue on an event:when event occurs one waiting processes can continue
More details (I) When a process waits for an event:
If the event is in the not-occurred state, the process is suspended and placed in a queue of processes waiting for the event to occur. When the event occur
All waiting processes are allowed to proceed
Event is changed to not occurred If the event is in the occurred state,
The process continues to execute Event state is changed to not
occurred
More details (II) When a process queues on an event:
If the event is in the not-occurred state, the process is suspended and placed in a queueof processes queued on the event. When the event occur
Only the first queued processes is allowed to proceed
Event is changed to not occurred If the event is in the occurred state,
The process continues to execute Event state is changed to not occurred
CSIM events and semaphores
Like binary semaphores, CSIM events can have two values:
occurred/not-occurred Occurred correspond to value of 1 Not-occurred corresponds to value
of 0 Set() method corresponds to V() Queue() method corresponds to P() Wait() method does not correspond
to any semaphore operation
Example:declaring and using an event
event *ev; //declare event ev
ev = new event("ev"); //initialize it
...
ev->wait(); // wait for event
...
ev->queue(); // queue on event
...
ev->set(); // set event
Example:arrays of events
const long NEV = 25;
event_set *eva; // declare array
eva = new event_set("ev array", NEV);
// initialize it events*/
...
(*eva)[5].wait();
...
(*eva)[5].set();
Example: waiting/queuing forany event in an array
i = eva->wait_any();
// i is index of event that occurred
or
i = eva->queue_any();
// i is index of event that occurred
Example: setting a maximum wait time
...
t = ev->timed_wait(MAXWAIT);
//wait for up to MAXWAIT time units
if (st ! = MAXWAIT) {
// success
...
}
CSIM MAILBOXES
Mailboxes
Allow for the asynchronous exchange of data between CSIM processes Any process may send a message to
any mailbox Any process may attempt to receive a
message from any mailbox
More details
A mailbox has two FIFO queues: A queue of unreceived messages A queue of waiting processes
At least one of the queues will be empty at any time Can either have messages waiting to
be received or processes waiting for messages but not both
Sending messages
CSIM uses non-blocking sends: When a process sends a message
If there is a waiting process The message is given to that
process Else
The message is placed in the message queue.
Receiving messages
CSIM uses blocking receives: When a process attempts to receive a
message, If there is an unreceived message
The message is given to the process
Else The process is placed in the
process queue
Observations
Non-blocking sends and blocking receives are the norm in most message passing systems CSP is the counter-example
Since messages are sent to and retrieved from a mailbox, this is a case of indirect communication
Messages
A message can be either A single integer or A pointer to some other data object.
If a process sends a pointer, it is the responsibility of that process to maintain the integrity of the referenced data object until it is received and processed We are simulating message passing
Example: a single mailbox
long msg_r, msg_s; // message variables
mailbox *mb; // declare mailbox mb
mb = new mailbox("mb"); // instantiate mailbox
...
mb->receive(&msg_r); // receive msg
...
mb->send(msg_s); // send msg
Example:setting a maximum wait time
...
st = mb->timed_receive(&msg_r, MAXWAIT);
// wait for up to MAXWAIT time units
if (st < MAXWAIT) {
//success
...
} // if
Example:arrays of mailboxes
const long NBOXES = 25;
mailbox_set *mba;
. . .
mba = new mailbox_set("mbox set", NBOXES);
Example: getting a message from any mailbox in an array
i = mba->receive_any(&msg);
// i is index of non-empty mailbox
Example: sending a message to a given mailbox in an array
(*mba)[3].send(msg);
Example:
st = mba->timed_receive_any(&msg, MAXWAIT);
if(st < MAXWAIT) {
// process message
...
} else {
// handle time out
...
} // if
MANAGING QUEUES
Queues
Each CSIM resource (facility, storage, buffer, mailbox, …) consists of One or more queues containing
waiting processes (suspended processes in CSIM lingo)
Resource-specific data structures CSIM allows programmer to manipulate
the contents of these queues
Example For facilities, the programmer can Find the process at the head of the
queue: pptr = f->first_process();
Find the process at the tail of the queue: pptr = f->last_process();
Remove a process from a facility queue : pptr = f->remove_process(pptr);
Insert a process in a facility queue: f->insert_process(pptr);
For more details
Check online documentation
GATHERING MORE STATISTICS
Tools
SIM provides four general-purpose statistics gathering tools: Tables Qtables Meters Boxes
Supplement standard statistics gathered by facilities and storages
Usage To obtain statistics other than mean
values for facilities and storages To obtain statistics for other model
components, such as mailboxes and events
To obtain statistics for selected submodels or for the model considered as a whole
To employ the CSIM run length control algorithms Stop the simulation once collected data
satisfy user’s accuracy requirements
Steps to be taken
Identify statistics of interest and which statistics gathering tools are appropriate
Declare a global pointer (variable) for each statistics gathering tool that will be used
Initialize each statistics gathering tool Add instrumentation (i.e., function calls) to
the model to feed data to the tools Generate reports
TABLES
Purpose To gather statistics about a sequence of
discrete entities such as Interarrival times Service times Response times
Tables do not store anywhere the recorded values They simply update their statistics
each time a value is included
Standard statistics
Minimum Maximum Range Mean Variance Standard deviation Coefficient of variation No quantiles (median, …)
Optional features Creation of a histogram Calculation of confidence intervals Computation of statistics for values in
a moving window
Types of tables
Tables can be Dynamic
Should be used by default Permanent
Not cleared when the reset function is called
Not deleted when rerun is called Used to gather data across multiple
runs of a model
Declaring and initializinga dynamic table
table *td;
td = new table("response times");
Declaring and initializinga permanent table
permanent_table *td;
td = new permanent_table("response times");
Using a table
To “insert” a value, use either td->tabulate(1.0);or td->record(1.0);
To generate reports For a specific table, use
td->report(); For all existing tables, use
report_tables();
Specifying a histogram
Prototype:void table::add_histogram(long nbucket,double min,double max)
Example:td->add_histogram(10, 0.0, 10.0); Will divide range from 0 to 10 into 10
classes or buckets
Confidence Intervals
CSIM can automatically compute confidence intervals for the mean value of any table td->confidence();
Must invoke method immediately after table has been initialized
We get 90, 95 and 98 percent confidence intervals
Moving window
Can specify that only the last n values are used in computing the statistics n is called the window size
Example: td->moving_window(1000);
Usually specified immediately after the table is initialized Can do it later but table must be
empty Can be used to remove initial bias
Other options
Can rename a table: td->set_name("elapsed time");
Can clear and reinitialize a table td->reset_table();
Can delete a dynamic table delete td;
The post office problem revisited (I)
#include <cpp.h> // header filefacility_ms *po; // the service centertable *tqueue, *tservice, *ttotal;const long nclerks = 2;
void customer();
The post office problem revisited (II)
extern "C" void sim() { // sim process create("sim"); // make it a process po = new facility_ms(“po", nclerks); tqueue = new table("Waiting times"); tservice = new table("Service
times"); ttotal = new table("Total times"); while (simtime() < 5000.0) { hold(exponential(1.0)); // delay customer(); // new customer } // while loop report(); // output results}// sim
The post office problem revisited (III) void customer() { double t0, t1, t2; create("customer"); t0 = simtime(); po->reserve(); t1 = simtime(); tqueue->record(t1 – t0); hold(exponential(1.0)); po->release(); t2 = simtime(); tservice->record(t2 – t1); ttotal->record(t2 – t0);} // customer
The post office problem revisited (IV)
void customer() { double t0, t2; create("customer"); t0 = simtime(); po->use(exponential(1.0)); t2 = simtime(); ttotal->record(t2 – t0);} // customer
Observations
If we use a use statement in the customer process, we can only have collected total times
QTABLES
Purpose To gather statistics about on an integer
function of time such as Queue length Population of a subsystem Number of available resources ...
Qtables record and gather statistics about time-averaged values
Qtables and Tables
Entering a value into a table is done through a tabulate() method
Updating a qtable is a two-step process:
qtbl->note_entry();...qtbl->note_exit();
Think of qtables as special tables for queues
Declaring and Initializing Dynamic Qtables A pointer to a dynamic qtable is declared
in a CSIM program as follows: qtable *qtd;
Before a qtable can be used, it must be initialized qtd = new qtable("queue length");
Initializing Permanent Qtables A qtable can be initialized as a
permanent qtable qtd = new
permanent_qtable("queue length");
Noting a Change in Value
Most common way for the value of a qtable to change is for it to increase or decrease by one. Customer joins/leaves a queue A resource is allocated/released
Use qtd -> note_entry();
...qtd->note_exit();
Special case
The value of a qtable can be changed To an arbitrary number
qtd->note_value(12); To an arbitrary floating (double)
qtd->note_value(1.75); The value of a qtable can be initialized
to an arbitrary floating (double) number qtd->set_initial_value(-1.0);
Producing reports
To generate a report for a specific qtable use qtd->report();
To generate reports for all existing qtables use report_qtables();
Report for a qtable will include the qtable name and all statistics
Histograms
To specify a histogram use qtd->add_histogram(
nbuckets, // number of bucketsmin, // minimum valuemax // maximum value);
Caution: The min and max parameters of add_histogram are of type long, not double as for tables
Confidence Intervals
CSIM can automatically compute confidence intervals for the mean value of any qtable
qtd->confidence();
Must invoke method immediately after qtable has been initialized
We get 90, 95 and 98 percent confidence intervals
Moving window
Specifying a moving window forces the qtable to use only the last n changes a computing the statistics n is called the window size (long int)
Use qtd->moving_window (n);
It is an error to specify a moving window for a qtable that is not empty.
More
Can rename, reset and delete qtables
qtd-> set_name ("number in queue");
qtd->reset_qtable (); delete qtd;
Reset does not clear qtable optional features like histogram, confidence intervals and moving window
The post office problem revisited (I)
#include <cpp.h> // header filefacility_ms *po; // the service centerqtable *tqueue, *tclerks, *tpo;const long nclerks = 2;
void customer();
The post office problem revisited (II)
extern "C" void sim() { // sim process create("sim"); // make it a process po = new facility_ms("po", nclerks); tqueue = new qtable("Queue"); tclerks = new qtable("Clerks"); tpo = new qtable("Post Office"); while (simtime() < 5000.0) { hold(exponential(1.0)); //
delay customer(); // new customer } // while loop report(); // output results}// sim
The post office problem revisited (III) void customer() { create("customer"); tqueue->note_entry(); tpo->note_entry(); po->reserve(); tqueue->note_exit(); tclerks->note_entry(); hold(exponential(1.0)); po->release(); tclerks->note_exit(); tpo-> note_exit();} // customer
The post office problem revisited (IV)
void customer() { create("customer"); tpo->note_entry(); po->use(exponential(1.0)); tpo->note_exit();} // customer
METERS
Meters
Used to gather statistics on the flow of entities past a specific point in a model
Can measure arrival rates completion rates allocation rates
Declaring and InitializingDynamic Meters To declare a dynamic meter,use
meter *md; To initialize the meter use
md = new meter(" completions");
Measuring passages at a meter Use
md-> note_passage();
For the statistics to be accurate, every entity of interest must Note its passage Do so at the correct time
Producing Reports
Can generate a report for a specified meter at any time md->report();
Can generate reports for all existing meters by calling the report_meters function report_meters();
Standard Report Options
Can request meters to produce histograms md ->add_histogram(
nbuckets, // longmin, // doublemax // double)
Can request meters to compute confidence intervals md ->confidence();
Other Options
Can rename, reset and delete meters md ->set_name(" departures"); md->reset(); delete md;
BOXES
Boxes
Conceptually enclose part or all of a mode
Gather statistics on The number of entities in the box The amount of time entities spend in
the box (i.e., the elapsed time).
Boxes, Tables and Qtables
Each box combines a table and a qtable Statistics on elapsed times are kept in
the table Statistics on number of entities in the
box are kept in the qtable Simplifies the programmer's task
Declaring and Initializing Dynamic Boxes To declare a dynamic box, use
box *bd; To initialize a dynamic box, use
bd = new box("system"); To make the box permanent, use
bd = new permanent_box("system");
Instrumenting the model
An entity enters a box by calling the enter method timestamp = bd->enter();
timestamp must be saved by the entity that entered the box
The entity exits the box by calling the exit method and passing to it the timestamp that it received upon entry bd->exit(timestamp);
Producing Reports
To generate a report for a specified box, use bd->report();
To generate reportsd for all existing boxes, use report_boxes();
Histograms
Can specify histograms For the elapsed times in a box;
bd->add_time_histogram(10, 0.0, 10.0);
For the population of a box bd->add_number_histogram(10, 0, 10);
Confidence intervals
Can specify confidence intervals For the elapsed times in a box
bd->time_confidence(); For the population of a box
bd->_number_confidence();
The post office problem revisited (I)
// Uses boxes
#include <cpp.h> // header filefacility_ms *po; // the service centerbox *bqueue, *bclerks, *bpo;const long nclerks = 2;
void customer();
The post office problem revisited (II)
extern "C" void sim() { // sim process create("sim"); // make it a process po = new facility_ms("po", nclerks); bqueue = new box("Queue"); bclerks = new box("Clerks"); bpo = new box("Post Office"); while (simtime() < 5000.0) { hold(exponential(1.0)); // delay customer(); // new customer } // while loop report(); // output results}// sim
The post office problem revisited (III) void customer() { double t0, t1; create("customer"); t0 = bqueue->enter(); t0 = bpo->enter(); po->reserve(); bqueue->exit(t0); t1 = bclerks->enter(); hold(exponential(1.0)); po->release(); bclerks->exit(t1); bpo->exit(t0);} // customer
The post office problem revisited (IV)
void customer() { double t0; create("customer"); t0 = bpo->enter(); po->use(exponential(1.0)); bpo->exit(t0);} // customer
STATISTICS GATHERING
Statistics gathering
Will show how to combine boxes and meters to gather statistics
Example
Want to instrument a service center and get
Arrival rates Departure rates Statistics about the whole service center Statistics about the server alone
Use Meters for both rates Boxes to isolate subsystems
The service center
Server
Will use two meters and two boxes One box around queue and server One box around server alone
MeterMeter
Declarations
facility *f;
meter *arrivals;
meter *departures;
box *queue_box;
box *service_box;
All entities are dynamic
Initialization
f = new facility("center");
arrivals = new meter("arrivals");
departures = new meter("completions");
queue_box = new box("queue");
service_box = new box("in service");
Instrumentation
arrivals->note_passage(); timestamp1 = queue_box->enter(); f->reserve(); timestamp2 = service_box-
>enter(); hold (exponential(0.8)); f ->release(); service_box->exit(timestamp2); queue_box->exit(timestamp1); departures->note_passage();}
Notes
The time at which the customer process enters the queue is the current time immediately before it issues the request() for the facility
The time at which the customer process enters the server is the current time immediately after it issues the request() for the facility
Every box requires each process using it to keep track of entry timestamps Timestamps must be local to the process
RUNNING A CSIM PROGRAM
Your program should run on one of the four Linux machines (linux01 to linux04) of our department.
Do not forget to add to your program:
#include <cpp.h> To compile your program with g++, you
should useg++ -DCPP program1.cpp –o program1 /usr/lib/libcsimcpp.a –lm
The basics
How to simplify your life
Create a file named csim containing g++ -DCPP $* /usr/lib/libcsimcpp.a –
lm Make it executable You can now write
csim program1.cpp –o program1
First example:A camper rental service
Hill Country Camper Rental Service has four campers available for rent to walk-in customers.
Rental times are uniformly distributed between three and seven days
Walk-in customers arrive randomly every two days, on the average.
If a camper is not available, the customer will go elsewhere.
Quantities of interest
Fraction of arriving customers that will be lost because no camper is available
Mean number of rented campers
Median number of rented campers
Fraction of arriving customers that will be lost if one of the four campers is in the shop for repairs
Basic entities
Two basic entities Customers Campers
We will use Processes to represent customers A multi-server facility to represent the
campers
How it will look
Campers
YesFree campers?
No
Customer process will start with a test
A narrative
Customer arrives at rental agency If there are no available campers,
he/she goes away Otherwise he/she
Reserves a camper Holds it for uniform (MAXRENTAL,
MINRENTAL) Releases the camper
Data gathering
Put a box around the multi-server facility representing them campers Use number_histogram to evaluate
the mean number of rented campers
Keep track of number of rented campers If all campers are rented out,
customer will be lost
Includes and defines
#include <cpp.h> // required
#define DURATION 360
#define NCAMPERS 4
#define MIART 2.0
#define MINRENTAL 3.0
#define MAXRENTAL 7.0
void customer();
Global declarations
facility_ms *campers; // service center
box *agency;
// other global variables
int nrented = 0; // no of rented campers
int ncust = 0; // no of customers
int nlost = 0; // no of lost customers
Sim process (I)
extern "C" void sim() { // sim process
create("sim"); // make this a process
campers = new facility_ms("campers", NCAMPERS); // create the facility
// initialize box
agency = new box("rental agency");
agency->add_number_histogram(5, 0, 4);
Sim process (II)
while(simtime() < DURATION) {
hold(exponential(MIART));
customer(); // generate next customer
} // while
Sim process (III)
report(); // produce statistics report
printf("\nNumber of customer arrivals: d\n", ncust);
printf("Number of lost customers: %d\n", nlost);
printf("Percentage of lost customers: %f percent\n", (nlost*100.0)/ncust);
} // sim
Customer process (I)
void customer() {
double time_in; // MUST BE LOCAL
create("customer"); // make this a process
ncust++; // note arrival
if (nrented == NCAMPERS) {
nlost++; // customer goes elsewhere
terminate (); // bye bye
} // if
Customer process (II)
// proceed with rental time_in = agency->enter(); //note entry campers->reserve(); // request service nrented++; // one more rented camper hold(uniform(MINRENTAL,
MAXRENTAL)); campers->release(); // return camper nrented--; // one less rented camper agency->exit(time_in); // note exit} // customer
Output (I) C++/CSIM Simulation Report (Version 19.0 for Linux x86)
Tue Apr 8 09:22:41 2008
Ending simulation time: 363.461
Elapsed simulation time: 363.461
CPU time used (seconds): 0.000
Output (II) FACILITY SUMMARY
facility service service through- queue response compl
name disc time util. put length time count
--------------------------------------------------------------------------------
campers fcfs 4.89966 2.022 0.41270 2.02209 4.89966 150
> server 0 4.77374 0.722 0.15132 55
> server 1 5.04442 0.597 0.11831 43
> server 2 4.60802 0.406 0.08804 32
> server 3 5.40136 0.297 0.05503 20
Output (III) BOX 1: camper rental agency
statistics on elapsed times
minimum 3.054523 mean 4.899663
maximum 6.959299 variance 1.309492
range 3.904776 standard deviation 1.144330
observations 150 coefficient of var 0.233553
statistics on population
initial 0 minimum 0 mean 2.043391
final 2 maximum 4 variance 1.265306
entries 152 range 4 standard deviation 1.124858
exits 150 coeff of variation 0.550486
Output (IV) cumulative
number total time proportion proportion
0 25.00858 0.068807 0.068807 *****
1 104.86629 0.288522 0.357328 ********************
2 105.44072 0.290102 0.647431 ********************
3 85.63595 0.235613 0.883043 ****************
>= 4 42.50915 0.116957 1.000000 ********
Total number of customer arrivals: 176
Number of lost customers: 24
Percentage of lost customers: 13.636364 percent
Estimating a median
• Median of number of rented campers isabove 1 but less than 2
• Assuming linearity, median is around 1.51
Observations
Could have decomposed sim process into three functions initialize() generateCustomers() displayResults()
Could have replaced request(), hold() and release() calls by campers->use(uniform(…);
Second Example:A RAID array
Have extra parity data P = A XOR B XOR C
A B C P
Second Example:A RAID array Can tolerate failure of one disk
Say disk A fails We can reconstitute its contents using
A = P XOR A XOR B XOR C
A B C P
X
Disk array reliability
Reliability R(t) of a system is the probability that will remain operational over a time interval [0. t ] given that it was operational at time t = 0 Not the same as availability Our focus is evaluating the risk of a
data loss during array lifetime
Limitations of Markov models
Require disk failures and disk repairs to be Poisson processes Disk repair times are not
exponentially distributed Disk failures are not independent
events A failing disk may overhead a disk
rack Disk failure rate vary over time
Disk failure rates
Disk MTTFs express failure rates over actual disk lifetime A disk with a MTTF of 1,000,000 hours
will not last an average of 114 years Disk MTTFs announced by
manufacturers are fairly optimistic Obtained by extrapolating stress tests Observed disk failure rates are much
larger
Quantities of interest (I)
Mean Time to Data Loss (MTTDL): Used in many studies Assumes that long-term data loss rate
of an array can be sued to predict its data loss rate during its actual lifetime
MTTDLs are measured in decades, it not centuries
Array actual lifetimes are 5 to 7 years
Quantities of interest (II)
Failure rate over first n years; Probability that array will not lose any
data over n years Better performance index
Reflects actual usage conditions
Our model
Will investigate failure rates over first n years of operation of array
Will start the array and stop the simulation when A data loss occurs Array exceeds its operational lifetime
and repeat the process until we get good confidence intervals for failure rates
Possible extensions
Use variable disk failure rates High during burn-in period Much lower during first or second
year Increase as disk age
Model correlated failures
CSIM implications
Have one process per disk Wait until first of
Data loss Array reached the end of its useful
lifetime 5 to 7 years
Program will use a timed_wait() on a“data loss” event Other solutions are possible
Entities
The disk drives Assumed to fail independently of each
other Not always true
Overheating disks in disk racks Disks from the same defective
batch
Constants
#include <cpp.h> // required #include <math.h> #define NDISKS 5 // number of disks in
array#define NYEARS 5 // lifetime of array
(years)#define MTTF 300000.0 // disk MTTF
(hours)#define MTTR 8.0 // disk MTTR (hours)#define NRUNS 400000L // number of
runs
Other global declarations
int nfailed; // number of failed disksdouble lifetime = NYEARS * 365 * 24;// simulation duration
event *dataloss;
void disk(int i);
Sim process (I)
extern "C" void sim() { // sim process int i; create("sim"); // make this a process dataloss = new event(“data loss"); // create NDISKS disk processes for (i=0; i < NDISKS; i++){ disk(i); } // for
Sim process (II)
// wait for data loss or // end of useful lifetime
dataloss->timed_wait(lifetime); report(); // produce statistics report if (simtime() < lifetime) {
printf ("Array failed at %3.0f\n", simtime());
} else { printf ("Array did not fail\n”);
} // if-else} // sim
Disk process (I)
void disk(int i) { create("disk"); while(simtime() < lifetime) { // expect failure hold(failures->exponential(MTTF)); // disk failed nfailed++; if (nfailed == 2) { dataloss->set(); terminate(); // the process } // if
Disk process (II)
// start repair process hold(repairs-
>exponential(MTTR)); // disk is repaired/replaced nfailed--; } // while} // disk
MORE ABOUT REPORTS
Tables, Qtables, …
To generate a complete report use report();
We can also generate partial reports: report_hdr(); report_facilities(); …
(check the online CSIM documentation)
Printing model statistics
To generate a report on the model statistics, use mdlstat();
Can also get specific reports on the number of events processed events_processed();
States of system entities
Use dump_status(); Can also get partial reports
status_processes (); status_next_event_list(); status_events (); status_mailboxes (); status_facilities (); status_storages ();
DEBUGGING AND TRACING
Tracing all state changes
To generate trace messages for all state changes, use trace_on();
To turn off tracing, use trace_off ();
Can use logical tests to turn and off trace messages
Can also use run time option –T to turn on trace messages
Tracing processes
Can trace one type of processes: trace_process ("customer");
Can trace a specific process: trace_process ("customer.100"); Number in string specifies the
process sequence number
Tracing a specific object
Object can be a facility, storage, event, or mailbox.
Use trace_object ("memory");
where string specifies the object name
Writing your own trace messages
Can include in your program: trace_object (“Your own text");
Redirecting trace output
Use fp = fopen ("trace", "w");
set_trace_file (fp);
MISCELLEANOUS OPTIONS
Restarting the model (I) Use rerun(); It will
Clear all non-permanent tables structures Kill all processes Reinitialize all facilities, events, mailboxes,
process classes, storage units, tables and qtables established before the first create(); statement
Eliminate all remaining facilities, storage units, events, …
Reset the clock to zero
Restarting the model (II)
Use rerun(); It will not:
Reset the random number generator Clear the permanent table structures
A good reason to use permanent tables