Each job is allowed to run for a time quantum q before being preempted and put back on the queue.
Example: q=1
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
A
A
A
A
A
A
A
A
B
B
B
C
C
C
Average_response_time = (0 + 0 + 1) / 3 = 0.33
The choice of q is important.
If q becomes infinite, RR becomes non-preemptive FCFS.
If q becomes 0, RR becomes simultaneously sharing of process (not possible due to context switching).
q should be a multiple of the timer interrupt interval
Initial set of simple assumptions: fourth adjustment
Each job (process/thread) runs the same amount of time.
All jobs arrive at the same time.
Once started, each job runs to completion (no interruption in the middle).
All jobs only use the CPU (no I/O).
The run time of each job is known.
(Almost) all processes perform I/O
When a job is performing I/O, it is not using the CPU. In other words, it is blocked waiting for I/O to complete.
It makes sense to use this time to run some other jobs.
Jobs with I/O
Job
Arrival Time
CPU Time
I/O
A
0
5
One per 1 sec
B
0
5
none
Normal STCF treating A as a single job
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
A
I/O
A
I/O
A
I/O
A
I/O
A
B
B
B
B
B
Average_turn_around_time = (9 + 14) / 2 = 11.5
Average_response_time = (0 + 9) / 2 = 4.5
STCF treating A as 5 sub-jobs
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
A
I/O
A
I/O
A
I/O
A
I/O
A
B
B
B
B
B
Average_turn_around_time = (9 + 10) / 2 = 9.5
Average_response_time = (0 + 1) / 2 = 0.5
Initial set of simple assumptions: No more assumption
Each job (process/thread) runs the same amount of time.
All jobs arrive at the same time.
Once started, each job runs to completion (no interruption in the middle).
All jobs only use the CPU (no I/O).
The run time of each job is known.
The fifth assumption is he worst assumption:
Most likely never happen in real life
Yet, without it, SJF/STCF becomes invalid.
The question
How do we schedule jobs without knowing their run time duration so that we can minimize turn around time and also minimize response time for interactive jobs?
Multi-level Feedback Queue (MLFQ)
Invented by Fernando Jose Corbato (1926 - 2019)
Ph.D. in Physics (CalTech)
MIT Professor
One of the original developers of Multics (Predecessor of UNIX)
First use of password to secure file access on computers.
Recipient of the 1990 Turing Award (The Nobel prize in computing)
Overview of MLFQ
Learn from the past to predict the future
Common in Operating Systems design. Other examples include hardware branch predictors and caching algorithms.
Works when jobs have phases of behavior and are predictable.
Assumption: Two categories of jobs
Long-running CPU-bound jobs
Interactive I/O-bound jobs
MLFQ: the queues
Consists of a number of distinct queues, each assigned a different priority level.
Each queue has multiple ready-to-run jobs with the same priority.
At any given time, the scheduler choose to run the jobs in the queue with the highest priority
If multiple jobs are chosen, run them in Round-Robin
MLFQ’s feedback rules 1 and 2
Rule 1: If Priority(A) > Priority(B), A runs and B doesn’t
Rule 2: If Priority(A) == Priority(B), RR(A, B)
Does it work well?
With only these two rules, A and B will keep alternating via RR, and C and D will never get to run.
What other rule(s) do we need to add?
We need to understand how job priority changes over time.
Attempt 1: How to change priority?
Rule 3: When a job enter the system, it is placed at the highest priority (the top most queue).
Rule 4a: If a job uses up an entire time slice while running, its priority is reduced (it moves down one queue).
Rule 4b: If a job gives up the CPU (voluntarily) before the time slice is up, it stays at the same priority level.
Example
System maintains three queues, in the order of priority from high to low: Q2, Q1, and Q0.
Time-slice of 10 ms
Initial: A single long-running jobAlong came a short job
Job A (Dark): long-running CPU intensive
Job B (Gray): short-running interactive
Major goal of MLFQ: At first, since the scheduler does not know about the job, it first assumes that is might be a short job (higher priority). If it is not a short job, it will gradually be moved down the queues.
What about I/O?
The interactive job (gray) only needs the CPU for 1 ms before performing an I/O. MLFQ keeps B at the highest priority before B keep releasing the CPU.
What are potentially problems?
Problem 1: Starvation
If new interactive jobs keep arriving, long running job will stay at the bottom queue and never get any work done.
Problem 2: Gaming the system
What if some industrious programmers intentionally write a long running program that relinquishes the CPU just before the time-slice is up (Job B).
Problem 3: What if a program changes behavior?
Starting out as a long running job
Turn into an interactive job
Attempt 2: Priority boost
Rule 5: After some time period S, move all the jobs in the system to the topmost queue.
Problem: Starvation
Rule 5 help guaranteeing that processes will not be staved. It also helps with CPU-bound jobs that become interactive
What S should be set to?
S is considered a voodoo constants (John Ousterhout)
requires some form of magic to set them correctly.
Too high: long running jobs will starve
Too low: interactive jobs will not get a proper share of the CPU.
Attempt 3: Better accounting
Rewrite of Rule 4 to address the issue of gaming the system.
Rule 5: Once a job uses up its time allotment at a given level (regardless of how many time it has given up the CPU), its priority is reduced.
Summary
Rule 1: If Priority(A) > Priority(B), A runs (B doesn’t)
Rule 2: If Priority(A) = Priority(B), RR(A, B)
Rule 3: When a job enter the system, it is placed at the highest priority (the top most queue).
Rule 4: Once a job uses up its time allotment at a given level (regardless of how many time it has given up the CPU), its priority is reduced.
Rule 5: After some time period S, move all the jobs in the system to the topmost queue.
MLFQ observes the execution of a job and gradually learns what type of job it is, and prioritize it accordingly.
Excellent performance for interactive I/O bound jobs: good response time.
Fair for long-running CPU-bound jobs: good turnaround time without starvation.
Used by many systems, including FreeBSD, MacOS X, Solaris, Linux 2.6, and Windows NT