Lezione T8 Gli scheduler CPU di Linux



Documenti analoghi
J. Assfalg Appunti di Sistemi Operativi

Algoritmi di scheduling

Scheduling della CPU:

Sistemi Operativi. Scheduling della CPU SCHEDULING DELLA CPU. Concetti di Base Criteri di Scheduling Algoritmi di Scheduling

Sistemi Operativi SCHEDULING DELLA CPU. Sistemi Operativi. D. Talia - UNICAL 5.1

Lo scheduler di UNIX (1)

Scheduling della CPU. Sistemi multiprocessori e real time Metodi di valutazione Esempi: Solaris 2 Windows 2000 Linux

Processi e Thread. Scheduling (Schedulazione)

Sistemi Operativi SCHEDULING DELLA CPU

Scheduling della CPU

Concetti di base. Scheduling della CPU. Diagramma della durata dei CPU-burst. Sequenza Alternata di CPU Burst e I/O Burst

Lo scheduling. Tipici schedulatori

Un sistema operativo è un insieme di programmi che consentono ad un utente di

Scheduling. Lo scheduler è la parte del SO che si occupa di

Lo schedulatore del kernel

SCHEDULATORI DI PROCESSO

scheduling Riedizione modifi cata delle slide della Prof. DI Stefano

Pag. 1. Introduzione allo scheduling. Concetti fondamentali. Scheduling della CPU. Concetti fondamentali. Concetti fondamentali. Algoritmi.

Scheduling della CPU

Sistemi Operativi. Scheduling dei processi

Scheduling. Sistemi Operativi e Distribuiti A.A Bellettini - Maggiorini. Concetti di base

La schedulazione. E.Mumolo

Il software di base comprende l insieme dei programmi predisposti per un uso efficace ed efficiente del computer.

Criteri di Scheduling Algoritmi di Scheduling Multiple-Processor Scheduling Asymmetric/Symmetric multiprocessing Processori Multicore

Corso di Informatica

Scheduling della CPU. Concetti fondamentali. Concetti fondamentali. Concetti fondamentali. Dispatcher. Scheduler della CPU

La Gestione delle risorse Renato Agati

Scheduling. Scheduling 14/12/2003 1/7

Sistemi Operativi Kernel

Scheduling. Livelli Algoritmi

1. Che cos è la multiprogrammazione? Si può realizzare su un sistema monoprocessore? 2. Quali sono i servizi offerti dai sistemi operativi?

Obiettivo della multiprogrammazione: massimizzazione dell utilizzo CPU. Scheduling della CPU: commuta l uso della CPU tra i vari processi

Lez. 4 Lo scheduling dei processi. Corso: Sistemi Operativi Danilo Bruschi

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Lezione 6. Sistemi operativi. Marco Cesati System Programming Research Group Università degli Studi di Roma Tor Vergata.

Capitolo 5: Scheduling della CPU! Scheduling della CPU! Concetti di Base! Alternanza di Sequenze di CPU- e I/O-Burst!

Scheduling della CPU. Contenuti delle lezioni del 23 e del 26 Marzo Sequenza alternata di CPU burst e di I/O burst.

Lo Scheduling Real Time in Linux. Universita degli studi di Roma La Sapienza Ivan Gualandri Matricola Relatore: Giorgio Richelli

Definizione di processo. Un processo è un programma (o una parte di una programma) in corso di esecuzione

Pronto Esecuzione Attesa Terminazione

Il Sistema Operativo. C. Marrocco. Università degli Studi di Cassino

Calcolatori Elettronici A a.a. 2008/2009

Scheduling. Dipartimento di Informatica Università di Verona, Italy. Sommario

Scheduling della CPU Simulazione in linguaggio Java

SISTEMI OPERATIVI. Prof. Enrico Terrone A. S: 2008/09

Con il termine Sistema operativo si fa riferimento all insieme dei moduli software di un sistema di elaborazione dati dedicati alla sua gestione.

FONDAMENTI di INFORMATICA L. Mezzalira

Sistemi Operativi (modulo di Informatica II) I processi

A intervalli regolari ogni router manda la sua tabella a tutti i vicini, e riceve quelle dei vicini.

ASPETTI GENERALI DI LINUX. Parte 2 Struttura interna del sistema LINUX

ESERCIZIO 1 (b) Dove è memorizzato il numero del primo blocco del file? Insieme agli altri attributi del file, nella cartella che contiene il file.

Coordinazione Distribuita

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

Il memory manager. Gestione della memoria centrale

Diagramma delle durate dei CPU burst. Lo scheduler della CPU. Criteri di scheduling. Dispatcher

Scheduling Introduzione Tipi di scheduler Scheduler di lungo termine (SLT) Scheduler di medio termine (SMT) Scheduler di breve termine (SBT)

GENERAZIONE PROCESSO FIGLIO (padre attende terminazione del figlio)

Sistemi Operativi GESTIONE DELLA MEMORIA SECONDARIA. D. Talia - UNICAL. Sistemi Operativi 11.1

Sistemi Operativi. Memoria Secondaria GESTIONE DELLA MEMORIA SECONDARIA. Struttura del disco. Scheduling del disco. Gestione del disco

Gestione dei processi. Marco Cesati. Schema della lezione. Blocco di controllo 2. Sezioni e segmenti. Gestione dei processi. Job.

Il problema del produttore e del consumatore. Cooperazione tra processi

Approccio stratificato

SISTEMI DI NUMERAZIONE E CODICI

Il Sistema Operativo. Funzionalità. Sistema operativo. Sistema Operativo (Software di base)

Tesina per l esame di Sistemi Operativi a cura di Giuseppe Montano. Prof. Aldo Franco Dragoni

Secondo biennio Articolazione Informatica TPSIT Prova Quarta

La memoria - generalità

Il Sistema Operativo (1)

STRUTTURE DEI SISTEMI DI CALCOLO

Sistema Operativo. Fondamenti di Informatica 1. Il Sistema Operativo

Introduzione al MATLAB c Parte 2

Computazione multi-processo. Condivisione, Comunicazione e Sincronizzazione dei Processi. Segnali. Processi e Threads Pt. 2

Gestione della memoria centrale

Il Sistema Operativo. Introduzione di programmi di utilità. Elementi di Informatica Docente: Giorgio Fumera

Università degli Studi di Padova Dipartimento di Matematica. - Corso di Laurea in Informatica

B+Trees. Introduzione

Prestazioni CPU Corso di Calcolatori Elettronici A 2007/2008 Sito Web: Prof. G. Quarella prof@quarella.

Sistemi Operativi MECCANISMI E POLITICHE DI PROTEZIONE. D. Talia - UNICAL. Sistemi Operativi 13.1

MECCANISMI E POLITICHE DI PROTEZIONE 13.1

GESTIONE DEI PROCESSI

Sistemi operativi. Esempi di sistemi operativi

Architettura (10/9/2003) Pag. 1/6. Cognome e Nome (in stampatello):

Informatica di Base - 6 c.f.u.

Introduzione. Coordinazione Distribuita. Ordinamento degli eventi. Realizzazione di. Mutua Esclusione Distribuita (DME)

Gli stati di un processo

Esempio: dest = parolagigante, lettere = PROVA dest (dopo l'invocazione di tipo pari ) = pprrlogvgante

Il Sistema Operativo

Sistema operativo: Gestione dei processi

5. Scheduling della CPU. 5.1 Concetti Fondamentali Lo scheduler della CPU

5. Scheduling della CPU

Linux I/O Scheduling overview

Gestione del processore e dei processi

10 - Programmare con gli Array

Definire all'interno del codice un vettore di interi di dimensione DIM, es. int array[] = {1, 5, 2, 4, 8, 1, 1, 9, 11, 4, 12};

Sistemi operativi e reti A.A Lezione 2

Sistemi Operativi GESTIONE DELLA MEMORIA CENTRALE. D. Talia - UNICAL. Sistemi Operativi 6.1

Strutturazione logica dei dati: i file

Cosa è un foglio elettronico

Sistemi Operativi. Processi GESTIONE DEI PROCESSI. Concetto di Processo. Scheduling di Processi. Operazioni su Processi. Processi Cooperanti

Transcript:

Lezione T8 Gli scheduler CPU di Linux Sistemi Operativi (9 CFU), CdL Informatica, A. A. 2013/2014 Dipartimento di Scienze Fisiche, Informatiche e Matematiche Università di Modena e Reggio Emilia http://weblab.ing.unimo.it/people/andreolini/didattica/sistemi-operativi 1

Quote of the day (Meditate, gente, meditate...) The design relies on the fact that interactive tasks, by their nature, sleep often. Con Kolivas (1977-) Anestesista, programmatore Il pioniere del desktop interattivo 2

Parametri di progetto di uno scheduler (Repetita juvant) Numero e formato delle code dei processi pronti. Algoritmo di scheduling per ciascuna coda. Criterio usato per spostare un processo in una coda con priorità maggiore. Criterio usato per spostare un processo in una coda con priorità minore. Criterio usato per scegliere la coda in cui inserire inizialmente un processo. 3

LINUX v1.2 4

Coda dei processi pronti (Ve ne è una sola; semplice semplice) Esiste una unica lista contenente tutti i processi attivati sulla macchina. Il primo elemento della lista è la task_struct di init. init_task... 5

Definizione delle priorità (Priorità statica, the UNIX way) Ogni processo ha una priorità statica (nice value o nice) (re)impostabile dall'utente. La priorità varia da -20 (priorità più alta) a +19 (priorità più bassa). Il valore di default è 10. Schema classico delle priorità in UNIX. Non è prevista una modifica dinamica delle priorità da parte del kernel. 6

Algoritmo di scheduling (Round Robin; what else?) L'algoritmo di scheduling pesca in modalità round robin pesata uno dei processi in TASK_RUNNING. Un processo in attesa da più tempo viene favorito rispetto ad un processo che attende da meno tempo. A parità di attesa, un processo a priorità più alta viene favorito rispetto ad un processo a priorità più bassa. A tal scopo, ad ogni processo è associato un contatore, inizializzato al valore della priorità statica. 7

Aggiornamento del contatore (Round Robin; what else?) Ad ogni invocazione di schedule(), l'intera lista è scandita ed i contatori aggiornati: contatore = (contatore >> 1) + priority Si sceglie il processo per cui contatore è massimo. 8

Modifica dinamica della priorità (Non pervenuta) Non esiste alcun meccanismo per la modifica dinamica della priorità in funzione della natura del processo. L'unica priorità esistente è quella statica. La priorità iniziale del processo è: il valore iniziale di default (10). oppure un valore impostato con il comando nice. 9

Problemi 1/3 (Tanti, purtroppo) L'algoritmo di scheduling è O(n) rispetto al numero di processi (una invocazione di schedule() una scansione lineare della lista). Che succede se schedule() è invocata migliaia di volte al secondo in un sistema server con migliaia di processi attivi? 10

Problemi 2/3 (Tanti, purtroppo) Non vi è alcuna differenziazione in classi; l'unico discriminante è una priorità statica. Che succede se un processo muta spesso la propria natura? Il programmatore deve reimpostare ogni volta la priorità statica a mano? Che succede ad un terminale interattivo che va in competizione con uno script di make? 11

Problemi 3/3 (Tanti, purtroppo) Vi è una unica lista globale. L'accesso alla lista va serializzato per impedire le modifiche concorrenti. I processori si accodano per accedere alla lista. Le prestazioni non scalano con il numero di processori. Questo non è un vero problema, dal momento che Linux v1.12 non supporta sistemi SMP. 12

LINUX v2.2 13

Differenze rispetto allo scheduler v1.2 (Classi di processi, goodness()) Lo scheduler del kernel v2.2 è una estensione di quello presente nella versione v1.2. Differenziazione dei processi in più classi tramite un insieme più ampio di priorità. Introduzione di una funzione (goodness()) per il calcolo della bontà di un processo (ovvero quanto è favorevole schedularlo). 14

Il nuovo schema di priorità (Da [-20, 19] a [0, 139]) Si usano 140 livelli di priorità. Livelli [0, 99]: usati da algoritmi di scheduling di tipo soft real time (SCHED_FIFO, SCHED_RR), che hanno sempre la precedenza sull'algoritmo standard. Livelli [100, 139]: corrispondono al vecchio intervallo [-20, 19] e sono utilizzati dall'algoritmo di scheduling di default (round robin pesato). 15

Classi di processi: SCHED_FIFO (Alta priorità) Impostabili staticamente dall'utente all'avvio del processo. SCHED_FIFO: FCFS senza prelazione soft real time. Opera ad una priorità in [0, 99]. Un processo non si ferma se non quando termina o richiede I/O. Occhio: pericolo di stallo della macchina in caso di ciclo infinito! 16

Classi di processi: SCHED_RR (Alta priorità) Impostabili staticamente dall'utente all'avvio del processo. SCHED_RR: RR soft real time. Opera ad una priorità in [0, 99]. 17

Classi di processi: SCHED_OTHER (Bassa priorità) Impostabili staticamente dall'utente all'avvio del processo. SCHED_OTHER: algoritmo di scheduling RR pesato (derivato da quello presente in v1.2). Opera ad una priorità in [100, 139] ed è pertanto sempre battuto da SCHED_FIFO o SCHED_RR. Occhio: rischio di starvation in caso di esecuzione con un processo CPU-bound soft real time! 18

Criterio di scelta del processo (Priorità + algoritmo) Algoritmo multilivello. Passo 1: si individua il processo con priorità più alta nella lista dei processi. Passo 2: si applica l'algoritmo di scheduling associato al processo. 19

La funzione goodness() (Stima dell'interattività di un processo) La funzione goodness() ritorna un peso (weight) nell'intervallo [-1000, 1000]. Il peso è usato per scegliere il processo da schedulare. -1000: mai selezionare questo processo. 1000: processo soft real time, da selezionare subito. Algoritmo: Classe == SCHED_FIFO SCHED_RR? Sì weight=1000 Processo gira su stesso processore? Sì weight += bonus Processo usa le stesse aree di memoria? Sì weight += bonus weight += priorità processo 20

Problemi 1/2 (Un po' meno) L'algoritmo di scheduling è O(n) rispetto al numero di processi (una invocazione di schedule() una scansione lineare della lista). Che succede se schedule() è invocata migliaia di volte al secondo in un sistema server con migliaia di processi attivi? 21

Problemi 2/2 (Un po' meno) Vi è una unica lista globale. L'accesso alla lista va serializzato per impedire le modifiche concorrenti. I processori si accodano per accedere alla lista. Le prestazioni non scalano con il numero di processori. Questo comincia ad essere un problema, dal momento che Linux v2.2 supporta architetture SMP. 22

LINUX v2.4 23

Differenze rispetto allo scheduler v2.2 (Classi di processi, goodness()) Lo scheduler del kernel v2.4 è una estensione di quello presente nella versione v2.2. Uso di una coda contenente solo processi in stato di pronto. Uso di quanti di tempo variabili (time slice). Uso di un sistema di schedulazione a crediti. 24

Time slice (Quanto di tempo variabile) Ciascun processo può eseguire al più per un intervallo di tempo calcolato dinamicamente (time slice). Il calcolo avviene mediante un sistema a crediti: un credito 10ms di esecuzione. un processo acquisisce un credito ogni volta che si blocca premio all'interattività. dopo l'esecuzione di una time slice si scala un credito. nessun credito niente processore. 25

Recrediting (Quanti crediti sono riassegnati ai processi?) Quando tutti i processi in stato TASK_RUNNING hanno esaurito i crediti, il kernel ricalcola il credito per tutti i processi (recrediting). Algoritmo di aggiornamento: next_credit = prev_credit / 2 + priority Si cerca di ridurre il credito a disposizione dei processi per non farli eseguire troppo a lungo. Se il processo è interattivo il credito aumenta. Se il processo non è interattivo il credito si 26 riduce.

Algoritmo di scheduling (Round Robin; what else?) L'algoritmo di scheduling pesca il processo migliore tramite la funzione goodness(), in modo analogo al kernel v2.2. La funzione goodness() tiene ora in conto anche dei seguenti aspetti: affinità al processore. crediti rimanenti. 27

Problemi 1/2 (Pochi, ma grossi) L'algoritmo di scheduling è O(n) rispetto al numero di processi. Una invocazione di schedule() una scansione lineare della run queue). Un recrediting una scansione lineare della run queue. 28

Problemi 2/2 (Pochi, ma grossi) I processori sono inattivi durante il recrediting. starvation dei processori (tanto più marcata quanti più sono). 29

LINUX V2.5.49 - V2.6.22 30

Differenze rispetto allo scheduler v2.4 (Parecchie; è una riscrittura da zero) Obiettivi. Favorire i processi interattivi indipendentemente dal carico di lavoro applicato al processore. Scalare bene le prestazioni dello scheduler con il numero di processi. il numero di processori. 31

Coda dei processi pronti (Una per CPU!) La coda contiene due array di priorità di 140 elementi cadauno (una coda per ciascuna priorità possibile). Array dei processi attivi (active): non hanno esaurito il tempo di esecuzione loro assegnato. Array dei processi spirati (expired): hanno esaurito il tempo di esecuzione loro assegnato. alta Priorità [0] [1] Active array Lista di task_struct Priorità [0] [1] Expired array Lista di task_struct bassa [140] [140] 32

Il difetto del Weighted Round Robin (L'algoritmo standard in pseudocodice O(n)) for (p = init_task; p!= init_task; p++) { if (p->prio!= MAX) Aging (per evitare la p->prio++; starvation del processo) if (p->prio > current->prio) switch_to(p); Si schedula il primo processo con priorità più alta trovato. } Il ciclo for cicla sull'intera lista dei processi e pesca quello a priorità più alta fra gli eseguibili. Algoritmo O(n) rispetto al numero di processi. Bisogna cercare di evitare il ciclo for sull'intera lista. 33

Un algoritmo O(1) rispetto ai processi (Ricorda molto da vicino la tecnica del double buffering per i videogiochi) 1.Trovare in tempo O(1) la coda di priorità più elevata in active contenente la task_struct di un processo eseguibile. 2.Se non esiste una task_struct, tutti i processi sono spirati. Si scambiano gli array active ed expired (operazione fattibile in tempo O(1)) e si ripete 1. 3.Sia next=task_struct in cima alla coda di priorità più elevata (O(1)). 4.Si ricalcola la priorità di next (O(1). 5.Si effettua un cambio di contesto a next (O(1)). 6.Quando next ha usato la sua timeslice, lo si inserisce nella coda di priorità opportuna nell'array expired (O(1)). 34 7.Si invoca schedule() per schedulare un altro processo (O(1)).

Come risolvere il passo 1. (Come trovare la coda con priorità più elevata senza scandirle tutte) Si usa una bitmap di 140 bit (5 interi a 32 bit). Nella coda i è presente la bit i=1 task_struct di un processo eseguibile. bit i=0 Nella coda i non è presente la task_struct di un processo eseguibile. L'istruzione assembly bsfl (Intel) individua in tempo costante (O(1)) il primo bit non nullo in una bitmap. 35

Stima dell'interattività (Il kernel riconosce i processi interattivi) Obiettivo della stima: aumentare in maniera dinamica la priorità di un processo interattivo. Criterio di interattività: frequenza di blocco processo. Frequenza elevata: processo I/O-bound Frequenza bassa: processo CPU-bound Implementazione: campo sleep_avg inserito nella task_struct del processo. Run blocked: si sottrae a sleep_avg il tempo di esecuzione dell'ultima timelice. Blocked run: si aggiunge a sleep_avg il tempo di blocco (fino ad un massimo di 10ms). 36

Calcolo dinamico della priorità (Il processo esegue tanto spesso quanto richiesto dalla sua natura) La funzione effective_prio(), definita nel file $LINUX/kernel/sched.c, calcola il boost di priorità da assegnare ad un processo in base alla sua interattività. Tale funzione assegna un bonus di priorità nell'intervallo [-5, +5]. Processo fortemente I/O-bound -5. Processo fortemente CPU-bound +5. 37

Calcolo dinamico della timeslice (Il processo esegue tanto tempo quanto richiesto dalla sua natura) La durata della timeslice è: memorizzata nel campo time_slice della task_struct. calcolata dalla funzione task_timeslice() nel file $LINUX/kernel/sched.c. Tale funzione scala la priorità statica (PS) di un processo in un valore nell'intervallo [5ms, 800ms]: PS < 120 time_slice = (140 PS) * 20 PS 120 time_slice = (140 PS) * 5 38

Alcuni valori di esempio (Valgono più di 1000 parole) Priorità PS NICE Time_slice Altissima 100-20 800 ms Alta 110-10 600 ms Normale 120 0 100 ms Bassa 130 10 50 ms Bassissima 139 19 5 ms 39

Una riflessione su sleep_avg (STOP! A che serve tutto questo? Qual è l'effetto sui processi?) La metrica sleep_avg è molto accurata! Un processo che si blocca spesso, ma che esaurisce la sua timeslice continuamente, non riceve un bonus grande. Effetto ricompensa per i processi interattivi. Effetto punizione per i processi non interattivi. Un task che riceve un bonus di priorità lo perde se comincia ad abusare del processore. Cambi di contesto non compensati da attese provocano la decrescita di sleep_avg e del bonus. 40

Una pecca dell'algoritmo O(1) (Un processo CPU-bound può rallentare un processo I/O-bound) Scenario. Un processo CPU-bound ed un processo I/O-bound sono in competizione per il processore. Il processo I/O-bound termina la sua timeslice per primo. Il processo CPU-bound continua a consumare la sua timeslice per molto più tempo. Il processo CPU-bound blocca il processo I/O-bound almeno fino all'esaurimento della sua timeslice! 41

Una euristica risolutiva (La classica pezza ) Se il processo è sufficientemente interattivo, al termine della sua timeslice non viene spostato nell'array expired viene reinserito nell'array active. Rationale: reinserendo il processo interattivo nell'array di priorità active, esso continua ad essere rischedulato immediatamente. 42

Aggiornamento delle timeslice (Rimettiamo insieme tutti i pezzi) scheduler_tick() in $LINUX/kernel/sched.c. Si decrementa time_slice nella task_struct del processo in esecuzione. Se time_slice == 0, la timeslice è spirata e bisogna decidere in che array piazzare la task_struct. Si invoca la macro TASK_INTERACTIVE() per capire se il task è sufficientemente interattivo. Si invoca la macro EXPIRED_STARVING() per capire se la runqueue ha processi in starvation. Se la runqueue non ha processi in starvation ed il task è sufficientemente interattivo, viene reinserito in active. 43

Problemi 1/2 (I vecchi problemi sono spariti; ne sorgono di nuovi) È complicato stimare l'interattività di un processo. I/O-bound deve essere schedulato più spesso. CPU-bound deve essere schedulato meno spesso e con timeslice più lunghe. È complicato calcolare una giusta durata. Timeslice troppo piccola elevato aggravio legato al cambio di contesto. Timeslice troppo grande scheduler degenera in FIFO (bene per il batch, pessimo per l'interattivo). 44

Problemi 2/2 (I vecchi problemi sono spariti; ne sorgono di nuovi) La priorità è relativa mentre la timeslice è assoluta. Due processi con NICE 0 ed 1: le timeslice sono di 100ms e 95ms 5% di differenza. Due processi con NICE 18 e 19: le timeslice sono di 10ms e 5ms 100% di differenza! Sono state progettate diverse euristiche per affrontare questi problemi. Problema: le euristiche possono essere sfruttate per provocare Denial of Service (fatta l'euristica, trovato l'inganno!). 45

LINUX V2.6.23-46

Differenze rispetto allo scheduler v2.5 (Parecchie; è una riscrittura da zero) Obiettivi. Semplificare lo scheduler, togliendo tutte le euristiche viste in precedenza. Rendere lo scheduler equo (fair) verso tutti i processi. Mantenere elevata l'interattività con gli utenti. Completely Fair Scheduler (CFS) 47

Fair Scheduling (CFS cerca di emulare il comportamento di uno scheduler ideale) CFS cerca di imitare al meglio il comportamento di uno scheduler multitasking ideale (Generalized Processor Sharing, GPS) con le seguenti caratteristiche: timeslice infinitesima. servizio simultaneo ad n processi con capacità di Un processo elaborazione pari ad 1/n. Servito a capacità massima della CPU. Tre processi Serviti simultaneamente ad un terzo della capacità massima della CPU. 48

Perché GPS? (Già, perché proprio GPS?) GPS ha latenza di servizio minima. I processi non possono essere serviti più celermente di quanto non riesca a fare GPS. Perché non implementare direttamente GPS? 49

Problema (GPS non è implementabile) GPS non è implementabile perché un processore non può servire simultaneamente più processi. No, usare più processori non vale! GPS è definito solo per un processore. No, non si può ridurre la timeslice ad un valore quasi nullo nell'algoritmo O(1). L'aggravio legato al cambio di contesto ammazzerebbe le prestazioni. Si deve implementare una approssimazione di GPS Ripensamento delle strutture dati. 50

Strategia implementativa 1/3 (Cambia parecchio rispetto all'o(1)) Si cambia l'ordinamento della coda di pronto. Non più FIFO con priorità. I processi sono ordinati in base a quanta CPU hanno ricevuto in meno rispetto a GPS. In tal modo si può scegliere in maniera efficiente il processo con il maggior bisogno di CPU. 51

Strategia implementativa 2/3 (Cambia parecchio rispetto all'o(1)) Non si usa una timeslice fissa per un processo. Si usa una sola timeslice, condivisa fra tutti i processi. Una volta esaurita la timeslice, tutti i processi devono essere stati schedulati. Ogni processo è schedulato almeno una volta nella timeslice. Approssimazione della schedulazione simultanea effettuata da GPS. 52

Strategia implementativa 3/3 (Cambia parecchio rispetto all'o(1)) Non si usa Round Robin per la scelta del processo. Si sceglie il processo che ha ricevuto meno CPU rispetto a GPS. CFS si comporta come GPS a tratti. 53

Scheduling latency (La timeslice condivisa da tutti i processi) La scheduling latency è la timeslice unica condivisa fra tutti i processi. Approssimazione di una timeslice infinitesima. Valore di default: 20ms ( applicazioni multimediali). Tunable: /proc/sys/kernel/sched_latency_ns Ciascun processo ottiene una uguale proporzione di timeslice. timeslice(task)=sched_latency_ns/nr_tasks. timeslice(task) non può essere inferiore a 4ms. Tunable per regolare la timeslice minima: /proc/sys/kernel/sched_min_granularity_ns. 54

Priorità e pesi (Il peso quantifica la priorità nelle formule dello scheduler) La priorità statica del processo (in [0, 139]) è usata per definire dei valori detti pesi (weight). I pesi servono per scalare le grandezze di un processo (fetta di timeslice associata, tempo di esecuzione effettivo) in funzione della sua priorità. I pesi sono calibrati sperimentalmente e decrescono con la priorità assoluta. Priorità=0: peso massimo Priorità=139: peso minimo 55

Calcolo dinamico del quanto di tempo (Il processo esegue quanto gli serve, entro 20 ms.) La timeslice è la scheduling latency media per processo, pesata con la frazione relativa del peso del processo considerato. timeslice(task) = [ sched_latency_ns/nr_tasks ] * [ weight(task) / Σ tasks weight (task) ] Rationale: più è elevata la priorità, più è basso il valore di priorità assoluta, più è alto il peso, più aumenta la frazione di timeslice assegnata. 56

Il tempo virtuale (Scorre più o meno rapidamente a seconda della priorità) Ciascun processo ha associato un tempo virtuale di esecuzione (virtual run time). Campo vruntime della task_struct. Durante l'esecuzione di un processo, il tempo virtuale cresce: normalmente alla priorità standard (120). più lentamente a priorità più alte (<120). più velocemente a priorità più basse (>120). 57

Aggiornamento del tempo virtuale (Scorre più o meno rapidamente a seconda della priorità) Ad ogni rischedulazione viene ricalcolato il peso del processo uscente. Il valore vruntime è aumentato del tempo di esecuzione delta_exec in maniera proporzionale al rapporto fra la priorità standard e quella attuale. vruntime = [vruntime+delta_exec] * [ weight(prio=120) / weight(prio) ] Rationale: più elevata è la priorità assoluta, più è alto il peso, più lentamente cresce vruntime. 58

L'algoritmo di scheduling (Molto semplice) Si sceglie il processo eseguibile il cui vruntime è minimo. Problema: vruntime può andare in overflow. In tal caso, il processo attuale è eseguito per sempre (vruntime è a 64 bit!). Soluzione: si sceglie il processo eseguibile per cui la differenza vruntime min_vruntime è minima. Tale differenza non è soggetta ad overflow. 59

La coda di pronto (Non è più una coda!) Come pescare efficientemente (O(1)) il processo con differenza vruntime min_vruntime minima? Si usa un albero rosso-nero (red-black tree) di task_struct ordinate secondo la chiave vruntime min_vruntime. 60

L'albero rosso-nero (Ed alcune osservazioni di contorno) Δ = vruntime - min_vruntime Δ = 0 Δ = 100 Δ = 300 Viene sempre selezionato il processo che si trova in fondo a sinistra. Δ = 400 Δ = 150 Δ = 410 Inserimento: O(log n) Cancellazione: O(log n) Aggiornamento: O(log n) Estrazione minimo: O(1) vruntime e min_vruntime sono aggiornati ad ogni cambio di contesto oppure interruzione. I processi tendono a spostarsi da sinistra verso destra man mano che eseguono. I processi a priorità più alta si spostano più lentamente. 61

Fairness fra utenti diversi (Finora i processi sono stati considerati tutti appartenenti ad un utente) Si supponga di avere 25 processi, di cui 20 relativi ad un utente A. 5 relativi ad un utente B. CFS cerca di essere fair con tutti l'utente A ottiene una fetta di CPU molto più consistente rispetto all'utente B. Si rende necessario estendere i meccanismi di fairness a gruppi di processi. 62

Scheduling gerarchico (Si schedulano processi e gruppi di processi) A partire dal kernel v2.6.24 è stato aggiunto il supporto per la schedulazione gerarchica (hierarchical scheduling). Si introduce una nuova struttura dati: struct sched_entity (definita in $LINUX/include/linux/sched.h) che rappresenta un gruppo di processi. Ogni entity ha un suo vruntime e un suo peso, calcolato in maniera analoga a quanto visto prima. 63

L'albero rosso-nero, task e entity (Si schedulano prima le entity e poi i singoli processi) Δ = vruntime - min_vruntime Entity rappresentante il gruppo dei processi dell'utente A. 1 3 Δ = 0 2 Δ = 100 Task_struct dei processi appartenenti al gruppo dell'utente A. Entity rappresentante tutti i processi. Entity rappresentante il gruppo dei processi dell'utente B. Δ = 300 1. Si parte dalla entity rappresentante tutti i processi. Δ = 400 2. Si schedula la entity relativa ai processi del gruppo A (ha un vruntime più basso). Δ = 150 Δ = 410 3. Si schedula il processo con più fame di CPU nel Task_struct dei processi gruppo A (vruntime=0). 4. Si cambia contesto a tale appartenenti al gruppo processo. 64 dell'utente B.