Tutorial 2 Erindale: Thu@3pm 970123 ========== St George: Thu@6pm CSC354, Spring 1997 Tutorial notes, T2 ========================================================================= Announce: - ps1 handed out today (Due: Feb 13) Topics: - Review of timing diagram for last week's example - Review of CSIM structures - CSIM example, gensys.c - Other CSIM features (1) Review of Timing for ex1.c (csim.example) - Remember, in CSIM, simulated time only passes when the csim hold() statement is used. /* Only PARTS of the code for ex1.c are shown below */ sim() { create ("sim"); f = facility ("facility"); for (i=1 ; i<=NARS ; i++) { hold (expntl(IATM)); /* Simulated time passes */ cust (); } ... } cust() { create ("cust"); reserve (f); hold (expntl(SVTM)); /* Use facility f */ release (f); } - Simulated Time Line Suppose, expntl(IATM) returns: 1.5, 2.0, 1.0 expntl(SVTM) returns: 1.0, 1.5, 0.5 Simulated 0 1 2 3 4 5 6 Time +-------+-------+-------+-------+-------+-------+ | | | 1.5 3.5 4.5 XXXXXXXXX XXXXXXXXXXXXX X=facility f XXXXX used \___/\____/ wait run \_________/ elapsed time (2) Review of CSIM structures needed for gensys.c example FACILITY - usually represents system resources that are consumed by processes. Declare/Init: FACILITY f; f = facility ("facility"); FACILITY f; f = facility_ms ("facility", 3); FACILITY f[4]; facility_set (f, "facility", 4); Scheduling Discipline: set_servicefunc (f, pre_res); set_servicefunc (f, fcfs); ... Usage: use (f, 2.3); /* for any scheduling discipline */ reserve (f); hold (2.3); /* only for fcfs */ release (f); STORAGE - a resource that can be partially allocated to a requesting CSIM process. Declare/Init: STORE s; s = storage ("mem", 20); STORE s[3]; storage_set (s, "mem", 20, 3); Usage: allocate (5, s) deallocate (2, s); - if the allocate command is given and there is not enough available memory, the requesting process is queued in its priority order. EVENT - used to synchronize operation of CSIM processes - an event is in either the not_occurred or the occured state. Declare/Init: EVENT ev; ev = event ("done"); EVENT ev[4]; event_set (ev, "done", 4); Usage: wait (ev); - process is queued (suspended) until event ev is set (another active process uses the set() statement on this event). set (ev); - set event ev to occurred state (all processes return to active state). - then put event ev in not_occurred state clear (ev); - set event ev to not_occurred state. TABLE - contains statistical summary of values recorded in it. Declare/Init: TABLE t; t = table ("name"); HIST h; h = histogram ("name", 10, low, high); Usage: record (3.2, t); QTABLE - used to maintain information on the behaviour of a queue of processes. Declare/Init: QTABLE qt; qt = qtable ("name"); QHIST qh; qh = qhistogram ("name", 10); Usage: note_entry (qt); note_exit (qt); - used to collect data that looks like queue length data. - use note_entry before scheduling to a facility, and use note_exit afterwards. (3) gensys.c example - cpu is declared to be a two-serer facility. - disk drives are a set of four single-server facilities. - main memory has a maximum of 100 units of memory available. (a) "sim" process - initializes 2000 jobs and advances the simulated time clock between each job generation. - waits for all jobs to complete (event done) - reports the default CSIM statistics (report()) (b) "job" process - set priority for this job process, based on arrival order (i.e., job 1->priority 1, job 2->priority 2) - allocate memory amount (a value between 5 & 50) (amt) - determine the total CPU amount used by this job (cpt) loop till total is small... - pick a disk and schedule to it (process io()) - schedule a small cpu amount & decrement total by this amount - deallocate memory - also record response time (time from when this process started until it finished using resources) - uses a qtable to record when the job started (note_entry) and when it finished using all resources (note_exit). (c) main memory - when each job allocates memory (a random amount between 5 and 50), it will suspend if there is not enough memory available. - the suspended jobs will resume when the deallocate function frees up enough memory for the process to run. (d) cpu - cpu is a two-server facility that uses the pre_res scheduling discipline. Higher priority processes will prempt lower priority processes, so that the higher priority process at the facility will always finish using it first. Prempted processes eventually are rescheduled and complete. - generate the total amount of cpu, but only schedule small amounts of cpu at a time. For each small amount scheduled, we also schedule some io and wait for it to complete (event iodone). - we decrement the total cpu amount by the small amount, and continue to schedule small amounts of io and cpu until we have used the total amount of cpu. (e) disk drives - randomly select a disk between 0 and 3 (j) - use this disk facility using the fcfs scheduling discipline (reserve/hold/release) for the disk service interval (expntl(MNDSK)) - signal job process when done (iodone) /* CSIM Example of General Computer System */ /* This model simulates a system with memory, a cpu, and disk drives. Jobs arrive (are generated), queue for memory, and then compete for the cpu and disk drives. */ #include "csim.h" #define NJOBS 2000l /*number of jobs*/ #define NCPUS 2l /*number of cpu's*/ #define NDISKS 4l /*number of disks*/ #define AMTMEM 100l /*amount of memory*/ #define INTARV 1.0 /*job interarrival interval*/ #define MNCPU 0.25 /*mean cpu interval*/ #define MNDSK 0.030 /*mean disk service interval*/ #define TOTCPU 1.0 /*total cpu time*/ #define EPS 0.0005 /*tolerance */ FACILITY cpu; /*pointer to cpu facility */ FACILITY disk[NDISKS]; /*pointers to disk drives*/ STORE mem; /*pointer to memory */ EVENT done; /*pointer to event */ TABLE resp_tm; /*pointer to statistics table */ QTABLE sys_q; /*pointer to system qlen table */ int act; /*count of active jobs */ sim() /*1st process - job generator */ { long i; /* used to count jobs */ create("sim"); /* declare resources and tables */ cpu = facility_ms("cpu", NCPUS); /* 2-server cpu facility,*/ set_servicefunc(cpu, pre_res); /* with pre_res policy*/ facility_set(disk, "disk", NDISKS); /* 4 disk facilities set*/ mem = storage("memory", AMTMEM); /* memory storage */ done = event("done"); /* signal last job done */ resp_tm = table("resp time"); /* response time table */ sys_q = qtable("system que"); /* system queue table */ max_events(1000l) /* generate arrivals */ act = NJOBS; for(i = 1; i <= NJOBS; i++) { job(i); /*initiate job process */ hold(expntl(INTARV)); /*hold interarrival interval */ } wait(done); /* wait till all jobs complete*/ report(); /* print report */ } job(i) /* a job process */ long i; { long j; /* disk number */ long amt; /* memory amount */ EVENT iodone; /* indicates io done */ float cpt, x; /* cpu amounts */ TIME t; /* start time of job */ create("job"); set_priority(i); /*set job priority */ iodone = event("iodone"); /*declare local event */ t = clock; /*save start time */ amt = random(5l, AMTMEM/2); /*select size memory req.*/ note_entry(sys_q); /*enter system queue */ allocate(amt, mem); /*request (allocate) mem*/ cpt = erlang(TOTCPU, 0.5*TOTCPU); /*select cpu time req.*/ while(cpt > EPS) { j = random(0l, NDISKS-1); /*select disk drive */ io(j, iodone); /*initiate I/O process */ x = hyperx(MNCPU, 4.0*MNCPU); /*select next cpu intrvl*/ cpt -= x; use(cpu,x); /*use cpu x time units*/ wait(iodone); /*wait for IO to complete*/ } deallocate(amt, mem); /*return memory*/ record(clock - t, resp_tm); /*record response time */ note_exit(sys_q); /*exit system queue */ if(--act == 0) set(done); /*if last job, signal sim*/ } io(d, ev) /* I/O process */ long d; EVENT ev; { create("io"); reserve(disk[d]); /*reserve disk */ hold(expntl(MNDSK)); /*disk service interval*/ release(disk[d]); /*release disk*/ set(ev); /*signal I/O complete*/ } CSIM Simulation Report (Revision: 16, System: sun3) Date and time: Fri Feb 7 08:51:49 1992 Model: CSIM Time: 2062.502 Interval: 2062.502 CPU Time: 69.800 (seconds) Facility Usage Statistics +----------------------+---------------means----------------+---counts----+ facility srv disp serv_tm util tput qlen resp cmp pre cpu 0 pre_res 0.146 0.929 6.3 13096 cpu 1 pre_res 0.155 0.890 5.7 11818 cpu pre_res 0.151 1.819 12.1 2.834 0.235 24914 10218 disk[0] 0.030 0.054 1.8 0.056 0.031 3682 0 disk[1] 0.029 0.051 1.7 0.053 0.031 3574 0 disk[2] 0.030 0.053 1.8 0.055 0.030 3722 0 disk[3] 0.030 0.053 1.8 0.055 0.030 3718 0 Storage Usage Statistics +----------------+-------------------means---------------+---counts----+ storage capacity amt util srv_tm qlen resp cmp que memory 100 27.3 0.728 2.963 10.475 10.802 2000 1178 Table 1 Table Name: resp time mean 10.802 min 0.070 variance 1070.819 max 323.141 Number of entries 2000 QTable 2 QTable Name: system que Mean queue length 10.475 Max queue length 35 Mean time in queue 10.802 Number of entries 2000 (4) Other CSIM features reset(); - used to reset the statistics that have been collected for your model so far. - clears facilities, storages, and non-permanent tables and histograms. - useful for "warming up" a model. rerun(); - used to completely rerun your CSIM model. - all statistics and structures are reset. - useful to test your model using a different random number seed. MAILBOXES - this CSIM data structure is used for communication between processes. - a mailbox holds CSIM messages. CSIM processes can give commands to send or receive a message from a specified mailbox. Declare/Init: MBOX mb; mb = mailbox ("name"); Usage: send (mb, msg); - msg is a pointer to the message, so any data type may be sent. - if a message has already been sent, but hasn't been read yet, this message is queued in its arrival order. receive (mb, &msg); - receive the next message from the mailbox, mb. n = timed_receive (mb, &msg, time); - this process waits for the arrival of the message or for "time" time units to pass. - this function returns EVENT_OCCURRED or TIMED_OUT.