# STA 247, Assignment 3 - program. # Constants describing the disk. n.tracks <- 20 # Number of tracks on the disk read.time <- 5 # Time to read a track once the head is there (ms) seek.time <- 2 # Time to move the head by one track (ms) # Simulate the elevator or the closest-track scheme. The arguments are as # follows: # # scheme Either "elevator" or "closest" # n.accesses Number of accesses to simulate (default 2000) # n.proc Number of processes simulated (default 5) # # The value returned is a list with the following elements: # # time Total time taken for n.accesses accesses # track Number of each track accessed # satisfied Vector with the number of requests satisfied for each process # wait Vector with the wait time for each satisfied request simulate <- function (scheme, n.accesses=2000, n.proc=5) { if (scheme!="elevator" && scheme!="closest") { stop("Scheme must be either \"elevator\" or \"closest\"") } # Initialize the variables that record what happens. time <- 0 satisfied <- rep(0,n.proc) wait <- c() track <- rep(NA,n.accesses+1) # Set the probabilities of each process sticking to the current track. p.same <- (1:n.proc) / (n.proc+1) # Initialize the vector of tracks each process wants to access, and # a vector holding the time that each current request was first made. track.wanted <- sample (1:n.tracks, n.proc, replace=TRUE) request.time <- rep(0,n.proc) # Set up the initial state of the disk. track[1] <- sample(1:n.tracks,1) # Head is positioned randomly to start if (scheme=="elevator") { dir <- sample(c(-1,+1),1) # Set direction randomly } # Do the requested number of disk accesses. for (i in 1:(n.accesses-1)) { # The elevator scheme. if (scheme=="elevator") { # Move one more track in the same direction as before. track[i+1] <- track[i] + dir # Reverse direction if there's nothing to do in this direction. if (dir>0 && all(track.wantedtrack[i+1])) { dir <- -dir } # Find the closest track where data is wanted in the current direction. if (dir>0) { track[i+1] <- min(track.wanted[track.wanted>=track[i+1]]) } else { track[i+1] <- max(track.wanted[track.wanted<=track[i+1]]) } } # The closest track scheme. if (scheme=="closest") { # Look for requests at increasing distances from the current track. for (j in 0:n.tracks) { if (j==n.tracks) stop("Something wrong!") if (any(abs(track.wanted-track[i])==j)) { break; } } # If more than one track is the same distance away, choose randomly. if (sum(abs(track.wanted-track[i])==j)==1) { track[i+1] <- track.wanted[abs(track.wanted-track[i])==j] } else { track[i+1] <- sample(track.wanted[abs(track.wanted-track[i])==j],1) } } # Update time by the amount of time to seek and then read the track. time <- time + read.time + seek.time*abs(track[i+1]-track[i]) # See which processes have had their request satisfied, and pick new # requests for them. for (j in 1:n.proc) { if (track.wanted[j]==track[i+1]) { satisfied[j] <- satisfied[j]+1 wait <- c (wait, time-request.time[j]) request.time[j] <- time if (runif(1)>=p.same[j]) { track.wanted[j] <- sample(1:n.tracks,1) } } } } list (time=time, track=track, satisfied=satisfied, wait=wait) } # Do the stuff needed for the assignment. The argument is the random # number seed to use. do.stuff <- function (seed=1) { set.seed(seed) cl.sim <<- simulate("closest") set.seed(seed) el.sim <<- simulate("elevator") postscript("ass3-plots.ps",paper="letter",horizontal=TRUE) plot(cl.sim$track[1:200],xlab="closest track scheme",ylab="track number") plot(el.sim$track[1:200],xlab="elevator scheme",ylab="track number") hist(cl.sim$wait,xlab="Wait times for closest track scheme",main="") hist(el.sim$wait,xlab="Wait times for elevator scheme",main="") cat("Rates of requests being satisfied: elevator =", round(sum(el.sim$satisfied)/el.sim$time,3), ", closest track =",round(sum(cl.sim$satisfied)/cl.sim$time,3),"\n") cat("Average wait times: elevator =",round(mean(el.sim$wait),3), ", closest track =",round(mean(cl.sim$wait),3),"\n") dev.off() }