Vous êtes sur la page 1sur 19

El scheduler O(1) de Linux

Fernando R. Rannou
Departamento de Ingenieria Informatica
Universidad de Santiago de Chile

March 8, 2014
Los ticks (HZ)

El system timer es el reloj que interrumpe al procesador con una cierta


frecuencia. Por ejemplo, en arquitecturas i386
(include/asm-i386/param.h) se define

#define HZ 1000 /* internal kernel time frequency */

es decir, el timer hace tick 1000 veces por segundo o 1 tick cada un
milisegundo
Es importante no confundir este timer con la frecuencia del procesador.
Por ejemplo, en un procesador de 1.0 Ghz, el número de ciclos por ticks es

109 ciclos
= 106
103 ticks
Los jiffies
El kernel mantiene una variable llamada jiffies que contiene en
número de ticks que han ocurrido desde que se booteo el sistema
(<linux/jiffies.h>)

extern unsigned long volatile jiffies;

Al momento de booteo el kernel inicializa esta variable en cero y cada vez


que hay un tick, lo incrementa
Por lo tanto, como hay HZ ticks por segundo, hay HZ jiffies por segundo
y el tiempo que el sistema ha estado arriba es
jiffies
HZ

Los ticks y jiffies le permiten al kernel mantener la noción del tiempo


Por ejemplo, cuando un programador desea medir cuánto se demora en
ejecutarse un trozo de código, invoca llamdos al sistema que necesitan
saber cuánto tiempo ha transcurrido desde un evento anterior
Overflow de jiffies

En una máquina de 32 bits y system timer de 100 HZ, ¿Cuánto tiempo


pasará antes que se produzca overflow en la variable jiffies? ¿Y una de
1000 HZ?
El manejador del system timer

Cada vez que el system timer hace tick, se interrumpe al procesador y se


ejecuta el manejador de interrupciones del system timer
Este manejador está dividdo en dos partes:
1. Dependiente del hardware: periódicamenta guarda la hora
(tiempo), e invova a la rutina independendiente del hardware
llamada (en Linux) do timer()
2. Independiente del hardware: do timer() incrementa los jiffies,
actualiza tiempos de uso del sistema y del usuario, ejecuta timers
expirados y finalmente invova scheduler tick()
Introducción

Antes del kernel 2.6 el planificador tenia algunas limitaciones en la


presencia de muchas tareas
◮ Era un planificador O(n)

◮ Uno de las motivaciones era planificar eficientemente las hebras de


la máquina virtual de Java
◮ Cuando la carga es muy alta, el procesador consume mucho de su
tiempo en planificar y no en ejecutar procesos usuarios
◮ El algoritmo carecı́a de escalabilidad
◮ Un solo runqueue para todos los procesadores en SMP, es decir
cualquier tarea podı́a ser ejecutada en cualquier procesador
1. bueno para el balance de carga
2. no muy bueno en el uso de memoria cache
◮ Un solo lock para la runqueue
El nuevo scheduler kernel 2.6

Algunas de las caracterı́sticas más relevantes del nuevo scheduler son


1. Disponer un runqueue para cada procesador
2. Asignar quantum más grandes a procesos más importantes
3. Asignar (bind) procesos a procesadores (afinidad)
4. Implementar el algoritmo en O(1)
Afinidad de procesador

Cuando una tarea es afı́n a un procesador, sólo se ejecuta en dicho


procesador.
◮ Cada tarea tiene un bitmask que le indica a qué procesador es afı́n
◮ Normalmente, todos los procesadores están ñistado en el bitmask
◮ Procesos pueden modificar su bitmask
Estructura general
Cada procesador tiene un active y un expired runqueue con 140 colas de
prioridades cada una.
◮ 1-99: para tareas tiempo real
◮ 100-140: para tareas normales

La Prioridad Estática (SP) de un proceso


determina la cola a la que pertenece
La Polı́tica de Planificación determina
cómo ese proceso es planificado en su
procesador
Linux soporta polı́ticas de planificación para
tareas tiempo real y para tareas normales
Siempre se planifica primero la runqueue
activa no vacı́a con más alta SP
Note que en una misma runqueue pueden
haber procesos con polı́ticas distintas de
planificación
Polı́ticas de planificación tareas tiempo real
Un proceso con polı́tica tiempo real posee un SP entre 1 y 99
Existen dos polı́ticas de planificación de tareas tiempo real:
SCHED FIFO y SCHED RR
SCHED FIFO
1. Los procesos se ejecutan sin quantum de tiempo, pero no
apropiativamente
2. Cuando un proceso SCHED FIFO con mayor SP que el que está en
el procesador, llega a la runqueue, desapropia inmediatamente al
proceso
3. El proceso desapropiado retorna al frente de su runqueue
4. Un proceso nuevo siempre comienza al final de su runqueue, es decir
la cola se planifica FIFO.
5. Un proceso SCHED FIFO corre hasta que termina, o se bloquea por
I/O, o es desapropiado por un proceso SCHED FIFO con mayor
prioridad, o desaloja voluntariamente el procesador invocando
sched yield()
Polı́ticas de planificación tareas tiempo real

SCHED RR
1. Los procesos se ejecutan durante un quantum de tiempo, no
apropiativamente
2. Cuando expira el quantum, el proceso retorna al final de su runqueue
3. Si un proceso SCHED RR es desapropiado por un proceso con mayor
SP (ya sea SCHED FIFO o SCHED RR), retorna al frente de su
runqueue, y cuando vuelve al procesador, el quantum asignado es la
porción que no alcanzó a utilizar anteriormente
4. Un proceso SCHED RR corre hasta que expira su quantum, o se
bloquea por I/O, o es desapropiado por un proceso con mayor
prioridad, o desaloja voluntariamente el procesador invocando
sched yield()
El quantum para estas tareas es:

#define RR_TIMESLICE (100 * HZ / 1000)


Polı́ticas para tareas normales

Se entiende por tareas normales, todos aquellos procesos que no


requieren mecanismos especiales de real-time. Éstas son generalmente
son todas las tareas ejecutadas por usuarios de un sistema.
1. SCHED OTHER: Estándar Round-Robin, tiempo compartido
2. SCHED BATCH: para tareas ejecución batch
3. SCHED IDLE: para tareas background con con prioridades muy
bajas
Polı́ticas para tareas normales

En SCHED OTHER las tareas tienen una prioridad estática (SP) y una
prioridad dinámica (DP):
◮ SP por defecto es 120. Puede modificarse con nice

◮ −20 ≤ nice ≤ 19
◮ DP se calcula según SP y el tiempo promedio que la tarea ha estado
durmiendo

DP = max {100, min(SP − bonus + 5, 139)}

◮ Se planifica el proceso que está en frente de la cola no vacı́a con


mayor DP
◮ Un proceso SCHED OTHER puede ser desapropiado por tareas
SCHED FIFO y SCHED RR.
sleep avg y bonus
DP = max {100, min(SP − bonus + 5, 139)}

1. Cuando un proceso se despierta (se desbloquea), el tiempo que


estuvo durmiendo se suma a su tiempo total durmiendo
(sleep avg)
2. Cuando el proceso sale del procesador, se substrae de sleep avg el
tiempo que estuvo en el procesador
sleep avg bonus
0 ≤ sa < 100 ms 0
100 ≤ sa < 200 ms 1
bonus mide qué porcentaje del
200 ≤ sa < 300 ms 2
tiempo la tarea ha estado durmiendo
300 ≤ sa < 400 ms 3
400 ≤ sa < 500 ms 4 5 es neutral
500 ≤ sa < 600 ms 5
600 ≤ sa < 700 ms 6 10 favorece la prioridad en 5
700 ≤ sa < 800 ms 7 0 desfavorece la prioridad en 5
800 ≤ sa < 900 ms 8
900 ≤ sa < 1000 ms 9
1s 10
Arreglos

struct runqueue {
struct prioarray *active;
struct prioarray *expired;
struct prioarray arrays[2];
};

struct prioarray {
int nr_active;
unsigned long bitmap[5];
struct list_head queue[140];
};
¿Cuál proceso planificar?

Para cada runqueue existe un vector


de 5 enteros donde cada bit indica si
en dicha cola hay o no procesos
listos para ejecutarse.
La instrucción
find-first-bit-set
(hardware) se usa para dicha labor
El tiempo de búsqueda depende en
el número de colas, no de procesos
en la cola.
Una vez determinada la cola no
vacı́a de mayor prioridad, se planifica
la primera tarea en ella
Cálculo del quantum para SCHED OTHER


(140 − SP) × 20 if SP < 120
q=
(140 − SP) × 5 if SP ≥ 120

◮ 100 ≤ SP ≤ 139 es la prioridad estática


◮ Menor valor de SP indica mayor prioridad
◮ Tareas con mayor prioridad obtienes quantum más largos
◮ El quantum no depende de la prioridad dinámica

SP nice q
Priorida alta 100 -20 800 ms
110 -10 600 ms
Prioridad inicial 120 0 100 ms
120 +10 50 ms
Prioridad baja 139 +19 5 ms
Procesos interactivos

En Linux, se dice que un proceso es interactivo cuando

bonus − 5 ≥ SP/4 − 28

◮ Un proceso con prioridad 100 pasa a ser interactivo cuando su


tiempo promedio dormido es mayor que 200 ms
◮ Un proceso con SP por defecto (SP=120) pasa a ser interactivo
cuando su tiempo promedio dormido es mayor a 700 ms
◮ Procesos con baja prioridad (139) nunca llegan a ser interactivos

¿Es bueno ser un proceso interactivo?


Considerando interactividad de los procesos

Existe una interrupción que permite al scheduler realizar tareas rutinarias


y tomar decisiones respecto del proceso actualmente en el procesador
En Linux, cada 1 ms se invoca el manejador de interrupcciones
scheduler tick()
1. En cada tick, se decrementa el quantum de la tarea actualmente en
el procesador
2. Si el quantum llega a cero, el proceso sale, y
◮ Si es no interactivo, pasa a la cola de expirados
◮ Si es interactivo vuelve a la cola de activos
3. En cualquier caso, se recomputa la prioridad dinámica y se le asigna
un nuevo quantum
4. Note que si no hay procesos en la cola de activos, el proceso vuelve
a entrar al procesador

Vous aimerez peut-être aussi