Vai al contenuto
Sistemi Operativi

Pianificazione della CPU: FCFS, SJF, round robin e lo scheduler di Linux

Misure di prestazione, ottimalità di SJF dimostrata con lo scambio, media esponenziale delle raffiche, limite di attesa del round robin dimostrato, code multilivello, CFS.

Quando più processi sono pronti, lo scheduler decide chi usa la CPU e per quanto. Le scelte possibili privilegiano obiettivi diversi: finire tanti lavori, rispondere in fretta all’utente, essere equi, rispettare le scadenze. In questa lezione vediamo le misure di prestazione, gli algoritmi classici con la dimostrazione che “prima il più breve” minimizza l’attesa media, la stima delle durate, il round robin con il suo limite sul tempo di risposta, le priorità e lo scheduler di Linux.

Le misure

Per ogni processo si misurano:

  • il tempo di completamento (turnaround): dall’arrivo alla fine;
  • il tempo di attesa: il tempo passato pronto in coda, senza essere eseguito;
  • il tempo di risposta: dall’arrivo alla prima esecuzione, importante per i programmi interattivi.

Per il sistema conta il throughput, il numero di lavori completati per unità di tempo, e l’utilizzo della CPU. I processi alternano raffiche di calcolo (CPU burst) e attese di ingresso e uscita: i processi interattivi hanno raffiche brevi, quelli di calcolo raffiche lunghe.

FCFS e SJF

FCFS (first come, first served) esegue i processi nell’ordine di arrivo. È semplice ma soffre dell’effetto convoglio: un lavoro lungo davanti fa aspettare tutti quelli brevi dietro. SJF (shortest job first) esegue per primo il lavoro con la raffica più breve.

Diagrammi di Gantt con FCFS e con SJF
Quattro processi pronti all’istante 0 con raffiche di 5, 9, 6 e 2 unità. Con FCFS, nell’ordine P1, P2, P3, P4, l’attesa media è 9,75; con SJF, nell’ordine P4, P1, P3, P2, è 5,5.

Esempio. Con FCFS le attese sono 0, 5, 14, 20, media 9,75; con SJF sono 0 (P4), 2 (P1), 7 (P3), 13 (P2), media 5,5.

Teorema. Tra tutti gli ordinamenti senza prelazione di n lavori disponibili all’istante 0, SJF minimizza il tempo di attesa medio.

Dimostrazione (scambio). Si consideri un ordinamento in cui due lavori consecutivi A e B hanno durate a \gt  b, con A prima di B. Scambiandoli, l’attesa dei lavori precedenti e di quelli successivi non cambia (questi ultimi aspettano comunque a + b per i due). L’attesa di B diminuisce di a e quella di A aumenta di b: la somma diminuisce di a - b \gt  0. Quindi ogni ordinamento con una coppia consecutiva “lunga prima di breve” si può migliorare, e l’ottimo non ne ha: è l’ordinamento per durate crescenti, cioè SJF. ∎

Lo stesso argomento di scambio dimostra molti risultati di ottimalità nella pianificazione (lezione sulla programmazione della produzione di Gestione aziendale).

Stimare il futuro

SJF richiede di conoscere la durata della prossima raffica, che non si sa. La si stima con una media esponenziale delle raffiche passate:

    \[ \tau_{n+1} = \alpha t_n + (1 - \alpha)\tau_n \]

dove t_n è la durata misurata dell’ultima raffica e 0 \le \alpha \le 1 il peso della storia recente. È un filtro passa-basso del primo ordine (lezione sui sistemi a tempo discreto). La versione con prelazione, SRTF (shortest remaining time first), interrompe il processo in corso se ne arriva uno con raffica più breve del suo tempo residuo. Il rischio di entrambi è l’attesa indefinita (starvation) dei lavori lunghi, se continuano ad arrivare lavori brevi.

Round robin

Il round robin dà a ogni processo pronto, a turno, un quanto di tempo q; allo scadere il processo torna in fondo alla coda (è la transizione da esecuzione a pronto nel diagramma degli stati, lezione sui processi).

Teorema. Con n processi pronti e quanto q, nessun processo aspetta più di (n - 1)q prima del suo turno.

Dimostrazione. Davanti a un processo in coda ci sono al più n - 1 processi, e ciascuno usa la CPU al massimo per q prima di essere rimesso in fondo. ∎

Il quanto è un compromesso. Se q è grande il round robin diventa FCFS; se è piccolo la risposta è rapida, ma la commutazione di contesto, che dura s, pesa: la frazione di tempo utile è q/(q + s). Con s = 5 µs e q = 5 ms il costo è lo 0,1 %; con q = 50 µs sarebbe quasi il 10 %. Di solito il quanto si sceglie più lungo della raffica tipica dei processi interattivi, che così finiscono prima che scada.

Priorità e code multiple

Gli scheduler reali assegnano priorità: i processi interattivi o di sistema prima di quelli di calcolo. Per evitare l’attesa indefinita dei processi a bassa priorità si usa l’invecchiamento (aging): la priorità cresce con il tempo passato in attesa.

La coda multilivello con retroazione (MLFQ) impara la natura dei processi senza conoscerla in anticipo: un processo nuovo entra nella coda più prioritaria con quanto breve; se consuma tutto il quanto scende di livello, se si blocca prima resta in alto. I processi interattivi restano così in alto, quelli di calcolo scendono verso code con quanti più lunghi.

Lo scheduler di Linux

Lo scheduler di Linux per i processi ordinari, CFS (completely fair scheduler, sostituito dalla versione 6.6 dall’evoluzione EEVDF con lo stesso principio), cerca di dare a ciascun processo una quota equa della CPU. Tiene per ogni processo un tempo di esecuzione virtuale, che cresce mentre il processo è in esecuzione, più lentamente per i processi più importanti; esegue sempre il processo con il tempo virtuale minimo, conservando i processi in un albero binario bilanciato. Un processo che dorme molto (interattivo) accumula poco tempo virtuale e, quando si sveglia, va subito in esecuzione. L’importanza si regola con il valore “nice”: ogni passo cambia il peso di circa il 25 %.

Sui sistemi multiprocessore lo scheduler deve anche bilanciare il carico tra i core e, al contrario, tenere un processo sullo stesso core (affinità) per sfruttare le cache già piene dei suoi dati. Per i processi in tempo reale servono regole diverse, con scadenze garantite (lezione sui sistemi in tempo reale).

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x
()
x