Starvation, Stability, and Allocations

3.3.5 Starvation, Stability, and Allocations

Starvation may be a problem The problem with priority scheduling algorithms like multi-level feedback is that they run the risk of starving long jobs. As short jobs continue to arrive, they continuously populate the first queue, and the long jobs in lower queues never get to run. But selective starvation may be a feature However, it is debatable whether this is a real problem, as the continued arrival of short jobs implies that the system is overloaded, and actually cannot handle the load imposed on it. Under such conditions, jobs will necessarily be delayed by arbitrary amounts. Using multi-level queues just makes a distinction, and only delays the long jobs, while allowing the short ones to complete without undue delay. Exercise 62 Which of the previously described algorithms also suffers from starvation? The effect of the runtime distribution on starvation is also important. When the distribution is fat-tailed, a very small fraction of the jobs is responsible for a rather large fraction of the load where load is defined here as CPU seconds of actual com- putation. By starving only these jobs, the system can tolerate overload while still providing adequate service to nearly all jobs [2]. In fact, this is an example of a more general principle. When a system is over- loaded, it is extremely important to prioritize its work. Without prioritization, all processes are equal and all suffer an infinite delay at least for true processor shar- ing; short ones will eventually terminate when using finite quanta. Prioritization allows the system to selectively reject some jobs, at the same time giving reasonable service to others. As rejecting some jobs is unavoidable in overloaded conditions, it is better to do so based on system considerations and not at random. Unix avoids starvation by having negative feedback Starvation depends on prioritization being a one-way street. In multi-level feedback queues, as described above, a process’s priority can only drop. As a result, it may starve as new processes with higher priorities continue to arrive. But in the Unix scheduler priority is a two-way street: a process’s priority drops as it runs and accumulates CPU seconds, but it grows when it waits in the queue. This leads to a stabilizing negative feedback effect: the very act of running reduces your ability to run more. An example of how the priorities of 4 processes change over time is shown in the following figure. Periodic scheduling decisions that choose the process with the low- est priority value are indicated by dashed arrows from below, and periodic divisions of all priorities by 2 are indicated by arrows from above. Even though the processes 75 start with quite different priorities, they all get to run, and their priorities tend to converge to a relatively narrow range. priority high priority low reduced priority time The result of this behavior is that CPU allocations tend to be equalized — if there are many competing processes, they will eventually all get about the same share of the CPU. The only way that a process may get less than its peers is if it needs less, e.g. if it often blocks on IO. As a result it will have a higher priority, and on those occasions when it wants to run, it will get the processor first. Linux avoids starvation by using allocations An alternative approach for avoiding starvation is to impose pre-defined allocations. Each process is given an allocation of CPU seconds, and then they are all allowed to use up their allocations before anyone’s allocation is renewed. An allocation-based scheme is used in the Linux system. Linux divides its time into epochs. At the beginning of each epoch, every process receives an allocation. The allocation also doubles as a priority, so processes with a larger allocation also get a higher priority. The scheduler always selects the process with the highest priority that is, the process with the largest remaining allocation to run. But allocations may run out. When this happens, the process is effectively prevented from running until the epoch ends. The duration of epochs is somewhat flexible. An epoch ends, and all allocations are renewed, when the scheduler finds that it has no process that can be scheduled to run. This may happen because all processes have exhausted their allocations, or because all processes with remaining allocations are currently blocked waiting for various events. Linux sets process allocations based on scheduling considerations. But users or system administrators may also want to be able to control the relative allocations of different processes. This is enabled by fair-share scheduling. 76

3.3.6 Fair Share Scheduling