Last active
December 14, 2015 01:59
-
-
Save banderson623/5010787 to your computer and use it in GitHub Desktop.
My dirty cpu simulator. Comment out debug lines at the bottom for displaying cool things
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Consider a system running ten I/O-bound tasks and one CPU-bound task. | |
# Assume that the I/O-bound tasks issue an I/O operation once for every millisecond of CPU computing and that each I/O operation takes 10 milliseconds to complete; the CPU-bound task performs only computations. | |
# Also assume that the context-switching overhead is 0.1 milli-second and that all processes are long-running tasks. | |
# | |
# Find out the CPU utilization for a round-robin scheduler when: | |
# | |
# a. The time quantum is 1 millisecond | |
# | |
# b. The time quantum is 10 milliseconds | |
class Proccess | |
attr_reader :name | |
attr_accessor :debug | |
def initialize(name) | |
@name = name | |
@type = "cpu" | |
@operatingSum = 0 | |
@waitingSum = 0 | |
@isWaiting = 0; | |
@waiting = 0; | |
@debug = false | |
end | |
def do(available_time) | |
did_run = 0 | |
print "#{@name.downcase.ljust(3)}" if @debug | |
while(available_time > 0) do | |
if(canRun?) | |
print("x") if @debug | |
did_run += 1 | |
@operatingSum +=1 | |
_privateDo | |
else | |
print("-") if @debug | |
@waitingSum += 1 | |
@isWaiting = @isWaiting - 1; | |
@isWaiting = 0 if(@isWaiting < 0.0) # cleanup | |
end | |
available_time = available_time - 1 | |
end | |
print "| " if @debug | |
return did_run | |
end | |
def canRun? | |
@isWaiting == 0 | |
end | |
def _privateDo | |
end | |
def to_s | |
"#{@name} (#{@type.downcase})" | |
end | |
def summary | |
"#{@name.ljust(10)} [#{@type.ljust(10)} waited: #{@waitingSum.to_s.ljust(10)} cpu: #{@operatingSum.to_s.ljust(10)}]" | |
end | |
def get_type | |
@type | |
end | |
end | |
class IOBound < Proccess | |
def initialize(name) | |
super(name) | |
@waiting = 10; | |
@type = "i/o" | |
end | |
def _privateDo | |
if(@isWaiting == 0 ) | |
@isWaiting += @waiting | |
end | |
end | |
end | |
class Processor | |
attr_accessor :switch_time, :quantum | |
def initialize(quantum = 1) | |
@queue = [] | |
@switch_time = 0.1 | |
@quantum = quantum | |
@totalTime = 0.0 | |
@utilizedTime = 0.0 | |
end | |
def add(task) | |
@queue << task | |
end | |
def to_s | |
@queue.inspect | |
end | |
def run(runs=100) | |
index = 0; | |
puts "Running #{runs} times >> quantum: #{@quantum}, context switch expense: #{@switch_time} \nProcesses" + @queue.collect{|i| i.to_s}.join(", ") | |
while(@queue.size > 0 && index < runs) | |
item = @queue.shift | |
runTime = item.do(@quantum) | |
@totalTime += @switch_time + runTime | |
@utilizedTime += runTime | |
@queue << item | |
if(index % 5 == 0) | |
puts "\n" if item.debug | |
end | |
index += 1 | |
end | |
end | |
def summary | |
return "CPUTime: #{@utilizedTime.round}ms | TotalTime: #{@totalTime.round}ms | Utilization: #{((@utilizedTime/@totalTime)*100).round}%" | |
end | |
end | |
puts "Round Robin: 1 ms Quantum" | |
cpu = Processor.new(1) | |
# cpu.debug = true | |
cpu.add(Proccess.new("p0")) | |
(1..10).each do |i| | |
p = IOBound.new("p#{i}") | |
# p.debug = true | |
cpu.add(p) | |
end | |
cpu.run(500) | |
puts cpu.summary | |
puts "\n\n\nRound Robin: 10 ms Quantum" | |
cpu = Processor.new(10) | |
# cpu.debug = true | |
cpu.add(Proccess.new("p0")) | |
(1..10).each do |i| | |
p = IOBound.new("p#{i}") | |
# p.debug = true | |
cpu.add(p) | |
end | |
cpu.run(5000) | |
puts cpu.summary |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment