|  | 
 
  | 
  
   
    |  |  |  |  |  
    |  | We concentrate on the problem of scheduling the
    usage of a single processor among all the existing processes in the system |  
    |  | The goal is to achieve |  
    |  | High processor utilization |  
    |  | High throughput |  
    |  | number of processes completed per unit time |  
    |  | Low response time |  
    |  | time elapse from the submission of a request to
    the beginning of the response |  
    |  |  |  | 
 
  | 
  
   
    |  |  |  
    |  | Long-term: which process to admit |  
    |  | Medium-term: which process to swap in or out |  
    |  | Short-term: which ready process to execute next |  | 
 
  | 
  
   
    |  |  |  |  |  
    |  | Determines which programs are admitted to the
    system for processing |  
    |  | Controls the degree of multiprogramming |  
    |  | If more processes are admitted |  
    |  | less likely that all processes will be blocked |  
    |  | better CPU usage |  
    |  | each process has less fraction of the CPU |  
    |  | The long term scheduler may attempt to keep a
    mix of processor-bound and I/O-bound processes |  | 
 
  | 
  
   
    |  |  |  |  
    |  | Swapping decisions based on the need to manage
    multiprogramming |  
    |  | Done by memory management software and discussed
    intensively in chapter 8 |  
    |  | see resident set allocation and load control |  | 
 
  | 
  
   
    |  |  |  |  
    |  | Determines which process is going to execute
    next (also called CPU scheduling) |  
    |  | Is the subject of this chapter |  
    |  | The short term scheduler is known as the dispatcher |  
    |  | Is invoked on a event that may lead to choose
    another process for execution: |  
    |  | clock interrupts |  
    |  | I/O interrupts |  
    |  | operating system calls and traps |  
    |  | signals |  
    |  |  |  | 
 
  | 
  
   
    |  |  |  |  
    |  | User-oriented |  
    |  | Response Time: Elapsed time from the submission
    of a request to the beginning of response |  
    |  | Turnaround Time: Elapsed time from the
    submission of a process to its completion |  
    |  | System-oriented |  
    |  | processor utilization |  
    |  | fairness |  
    |  | throughput: number of process completed per unit
    time |  | 
 
  | 
  
   
    |  |  |  
    |  | Implemented by having multiple ready queues to
    represent each level of priority |  
    |  | Scheduler will always choose a process of higher
    priority over one of lower priority |  
    |  | Lower-priority may suffer starvation |  
    |  | Then allow a process to change its priority
    based on its age or execution history |  
    |  | Our first scheduling algorithms will not make
    use of priorities |  
    |  | We will then present other algorithms that use
    dynamic priority mechanisms |  | 
 
  | 
  
   
    |  |  |  |  |  
    |  | The selection function: determines which process
    in the ready queue is selected next for execution |  
    |  | The decision mode: specifies the instants in
    time at which the selection function is exercised |  
    |  | Nonpreemptive |  
    |  | Once a process is in the running state, it will
    continue until it terminates or blocks itself for I/O |  
    |  | Preemptive |  
    |  | Currently running process may be interrupted and
    moved to the Ready state by the OS |  
    |  | Allows for better service since any one process
    cannot monopolize the processor for very long |  | 
 
  | 
  
   
    |  |  |  
    |  | We observe that processes require alternate use
    of processor and I/O in a repetitive fashion |  
    |  | Each cycle consist of a (usually relatively
    short )CPU burst followed by a (usually longer) I/O burst |  
    |  | A process terminates on a CPU burst |  
    |  | CPU-bound processes have longer CPU bursts than
    I/O-bound processes |  | 
 
  |  | 
 
  | 
  
   
    |  |  |  |  
    |  | Selection function: the process that has been
    waiting the longest in the ready queue (hence, FCFS) |  
    |  | Decision mode: nonpreemptive |  
    |  | a process run until it blocks itself |  | 
 
  | 
  
   
    |  |  |  |  
    |  | A process that does not perform any I/O will
    monopolize the processor |  
    |  | Favors CPU-bound processes |  
    |  | I/O-bound processes have to wait until CPU-bound
    process completes |  
    |  | They may have to wait even when their I/O are
    completed (poor device utilization) |  
    |  | we could have kept the I/O devices busy by
    giving a bit more priority to I/O bound processes |  | 
 
  | 
  
   
    |  |  |  |  
    |  | Selection function: same as FCFS |  
    |  | Decision mode: preemptive |  
    |  | a process is allowed to run until the time slice
    period (quantum, typically from 10 to 100 ms) has expired |  
    |  | then a clock interrupt occurs and the running
    process is put on the ready queue |  | 
 
  | 
  
   
    |  |  |  
    |  | must be substantially larger than the time
    required to handle the clock interrupt and dispatching |  
    |  | should be larger then the typical interaction
    (but not much more to avoid penalizing I/O bound processes) |  | 
 
  | 
  
   
    |  |  |  |  
    |  | Still favors CPU-bound processes |  
    |  | A I/O bound process uses the CPU for a time less
    than the time quantum and then is blocked waiting for I/O |  
    |  | A CPU-bound process run for all its time slice
    and is put back into the ready queue (thus getting in front of blocked
    processes) |  
    |  | A solution: virtual round robin |  
    |  | When a I/O has completed, the blocked process is
    moved to an auxiliary queue which gets preference over the main ready queue |  
    |  | A process dispatched from the auxiliary queue
    runs no longer than the basic time quantum minus the time spent running
    since it was selected from the ready queue |  | 
 
  | 
  
   
    |  |  |  
    |  | Selection function: the process with the
    shortest expected CPU burst time |  
    |  | Decision mode: nonpreemptive |  
    |  | I/O bound processes will be picked first |  
    |  | We need to estimate the required processing time
    (CPU burst time) for each process |  | 
 
  | 
  
   
    |  |  |  |  
    |  | Let T[i] be the execution time for the ith
    instance of this process: the actual duration of the ith CPU burst of this
    process |  
    |  | Let S[i] be the predicted value for the ith CPU
    burst of this process. The simplest choice is: |  
    |  | S[n+1] = (1/n) S_{i=1 to n} T[i] |  
    |  | To avoid recalculating the entire sum we can
    rewrite this as: |  
    |  | S[n+1] = (1/n) T[n] + ((n-1)/n) S[n] |  
    |  | But this convex combination gives equal weight
    to each instance |  | 
 
  | 
  
   
    |  |  |  |  
    |  | But recent instances are more likely to reflect
    future behavior |  
    |  | A common technique for that is to use exponential
    averaging |  
    |  | S[n+1] = a T[n] + (1-a) S[n]  ;   
    0 < a < 1 |  
    |  | more weight is put on recent instances whenever a
    > 1/n |  
    |  | By expanding this eqn, we see that weights of
    past instances are decreasing exponentially |  
    |  | S[n+1] = aT[n] + (1-a)aT[n-1] + ... (1-a)^{i}aT[n-i]
    + |  
    |  | ... + (1-a)^{n}S[1] |  
    |  | predicted value of 1st instance S[1] is not
    calculated; usually set to 0 to give priority to to new processes |  
    |  |  |  | 
 
  |  | 
 
  | 
  
   
    |  |  |  
    |  | Here S[1] = 0 to give high priority to new
    processes |  
    |  | Exponential averaging tracks changes in process
    behavior much faster than simple averaging |  | 
 
  | 
  
   
    |  |  |  |  
    |  | Possibility of starvation for longer processes
    as long as there is a steady supply of shorter processes |  
    |  | Lack of preemption is not suited in a time
    sharing environment |  
    |  | CPU bound process gets lower priority (as it
    should) but a process doing no I/O could still monopolize the CPU if he is
    the first one to enter the system |  
    |  | SPN implicitly incorporates priorities: shortest
    jobs are given preferences |  
    |  | The next (preemptive) algorithm penalizes  directly longer jobs |  
    |  |  |  
    |  |  |  | 
 
  | 
  
   
    |  |  |  |  
    |  | Preemptive scheduling with dynamic priorities |  
    |  | Several ready to execute queues with decreasing
    priorities: |  
    |  | P(RQ0) > P(RQ1) > ... > P(RQn) |  
    |  | New process are placed in RQ0 |  
    |  | When they reach the time quantum, they are
    placed in RQ1. If they reach it again, they are place in RQ2... until they
    reach RQn |  
    |  | I/O-bound processes will stay in higher priority
    queues. CPU-bound jobs will drift downward. |  
    |  | Dispatcher chooses a process for execution in
    RQi only if RQi-1 to RQ0 are empty |  
    |  | Hence long jobs may starve |  
    |  |  |  | 
 
  | 
  
   
    |  |  |  
    |  | FCFS is used in each queue except for lowest
    priority queue where Round Robin is used |  | 
 
  | 
  
   
    |  |  |  |  
    |  | With a fixed quantum time, the turnaround time
    of longer processes can stretch out alarmingly |  
    |  | To compensate we can increase the time quantum
    according to the depth of the queue |  
    |  | Ex: time quantum of RQi = 2^{i-1} |  
    |  | Longer processes may still suffer starvation.
    Possible fix: promote a process to higher priority after some time |  | 
 
  | 
  
   
    |  |  |  |  
    |  | Which one is best? |  
    |  | The answer depends on: |  
    |  | on the system workload (extremely variable) |  
    |  | hardware support for the dispatcher |  
    |  | relative weighting of performance criteria
    (response time, CPU utilization, throughput...) |  
    |  | The evaluation method used (each has its
    limitations...) |  
    |  | Hence the answer depends on too many factors to
    give any... |  | 
 
  | 
  
   
    |  |  |  
    |  | In a multiuser system, each user can own several
    processes |  
    |  | Users belong to groups and each group should
    have its fair share of the CPU |  
    |  | This is the philosophy of fair share scheduling |  
    |  | Ex: if there are 4 equally important departments
    (groups) and one department has more processes than the others, degradation
    of response time should be more pronounced for that department |  | 
 
  | 
  
   
    |  |  |  |  |  
    |  | Has been implemented on some Unix OS |  
    |  | Processes are divided into groups |  
    |  | Group k has a fraction Wk of the CPU |  
    |  | The priority Pj[i] of process j (belonging to
    group k) at time interval i is given by: |  
    |  | Pj[i] = Bj + (1/2) CPUj[i-1] + GCPUk[i-1]/(4Wk) |  
    |  | A high value means a low priority |  
    |  | Process with highest priority is executed next |  
    |  | Bj = base priority of process j |  
    |  | CPUj[i] = Exponentially weighted average of
    processor usage by process j in time interval i |  
    |  | GCPUk[i] = Exponentially weighted average
    processor usage by group k in time interval i |  | 
 
  | 
  
   
    |  |  |  |  |  
    |  | The exponentially weighted averages use a = 1/2: |  
    |  | CPUj[i] = (1/2) Uj[i-1] + (1/2) CPUj[i-1] |  
    |  | GCPUk[i] = (1/2) GUk[i-1] + (1/2) GCPUk[i-1] |  
    |  | where |  
    |  | Uj[i] = processor usage by process j in interval
    i |  
    |  | GUk[i] = processor usage by group k in interval
    i |  
    |  | Recall that |  
    |  | Pj[i] = Bj + (1/2) CPUj[i-1] + GCPUk[i-1]/(4Wk) |  
    |  | The priority decreases as the process and group
    use the processor |  
    |  | With more weight Wk, group usage decreases less
    the priority |  |