1 10. Memoria Virtuale • Tutti i metodi di gestione della MP tentano di tenere in MP più processi possibile per aumentare la multiprogrammazione • Tenere un processo interamente in MP diminuisce il numero dei processi che posso tenere in MP • La Memoria Virtuale (MV) è una tecnica che permette la esecuzione di processi non completamente in MP 2 10. Memoria Virtuale ⇒ programmi più grandi della MP ⇒ programmi in esecuzione che assieme sono molto più grandi della MP ⇒ maggiore separazione fra memoria logica e memoria fisica • Arma a doppio taglio perché: ♦ aumenta I/O (verso BS) ♦ influenza lo scheduling della CPU 3 10.1 Le basi • Overlay e caricamento dinamico richiedono precauzioni e sforzi del programmatore, e non ottimizzano l’uso della memoria • I programmi non hanno bisogno di essere sempre interamente in MP; ad es: – codice per trattare condizioni di errore non usuali – array, liste, tabelle sono spesso dichiarate più ampie di quanto poi usato – alcune opzioni di programma sono raramente usate 1 4 10.1 Le basi 5 10.1 Le basi • Vantaggi: – memoria "virtuale" disponibile grandissima e sganciata da quella fisica (ad es. piena di buchi) – aumento del grado di multiprogrammazione e quindi aumento di utilizzo della CPU e di throughput – meno I/O per caricare un programma o fare swap dei programmi (comunque necessario per aggiustare dinamicamente il grado di multiprogrammazione) 6 10.1 Le basi – la programmazione è più semplice – gli utenti non hanno bisogni di gestire la memoria • Normalmente implementata come: – demand paging (paginazione su richiesta): spesso – demand segmentation: più raramente perché più complessa e meno efficiente 2 7 10.2 Demand Paging • Simile a paginazione + swapping, con uno swapper pigro che porta in MP una pagina solo se serve • Swap è un termine improprio perché non si scambiano in memoria interi processi, ma solo pagine, cercando di indovinare quali pagine occorrono e si portano in MP solo quelle ⇒ il tempo di swap diminuisce 8 10.2 Demand Paging • Necessario supporto hardware per sapere quali pagine sono in memoria e quali su disco ⇒ valid/invalid bit può essere usato (anche) per questo 9 10.2 Demand Paging 3 10 10.2 Demand Paging • Accesso alle pagine valid (residenti in memoria) procede normalmente • Accesso alle pagine invalid → trap: – non è necessariamente "colpa" del programma – può essere causata da mancata paginazione del SO – può essere in programma che sbaglia e esce (tenta!) dal suo spazio • La pagina richiesta viene presa da BS e portata in MP 11 10.2 Demand Paging • Procedura di gestione di page-fault – 1. Riferimento (hw) – 2. Trap per invalid bit (hw, poi tutto SO) – 3. Test se accesso legale o illegale (via la PT stessa in genere) – 4. Se illegale terminare il processo; se legale dobbiamo portare in memoria la pagina – 5. Troviamo un frame libero in MP (o lo liberiamo) 12 10.2 Demand Paging • Procedura di gestione di page-fault – 7. Quando l’I/O è completato, correggiamo la PT: valid bit, indirizzo fisico – 8. Rimettiamo Ready il processo, ri-eseguendo la istruzione che ha dato trap 4 13 10.2 Demand Paging 14 10.2 Demand Paging • Notare: – Quando il processo ha dato trap, il suo contesto è stato salvato e viene ripristinato prima di metterlo Running – Il processo può anche essere fatto partire senza alcuna pagina in MP! • I processi tendono ad avere località di riferimenti =:= accedere ad un insieme limitato di pagine, che cambia lentamente 15 10.2 Demand Paging • Supporto hardware: lo stesso di paginazione più swapping • Le istruzioni devono essere ri-eseguibili dopo un page fault: – problema con istruzioni che accedono e modificano molte parole – ad es. MVC che sposta fino a 256 Byte, anche sovrapposti, oppure autodecrement (PDP11like) 5 16 Esempio • C = A+B 1 Caricamento dell’istruzione 2 Caricamento di A 3 Caricamento di B 4 Somma A e B 5 Memorizzazione in C 5 C = A++ 17 10.2 Demand Paging – microcodice deve testare che gli operandi siano tutti in memoria, oppure si tengono in CPU le locazioni modificate e si ripristinano in caso si trap – Questi sono problemi solo per il demand paging 18 10.3 Prestazioni della paginazione su richiesta • Calcoliamo l’effective access time – memory access time, ma, da 10 a 200nsec – p = probabilità di page fault eat = (1-p) * ma + p * page_fault_service_time • Vedere sul libro i dettagli delle 12 cose da fare per servire il page-fault. Tre componenti: – 1. Servire la trap di page-fault – 2. Portare in memoria la pagina – 3. Fare ripartire il processo 6 19 10.3 Prestazioni della paginazione su richiesta • Con attenta codifica, 1 e 3 richiedono solo alcune centinaia di istruzioni, da 1 a 100 microsec • Il tempo di 2 dipende dalla latenza del disco (8msec), il tempo di seek (15 msec), il tempo di trasferimento (1msec), esecuzione di istruzioni (1msec) → 25msec+tempo di accodamento! 20 10.3 Prestazioni della paginazione su richiesta • 1 e 3 sono trascurabili di fronte a 2; Se ma=100nsec → – eat=(1-p)*100+p*25*106 = 100+24.999.900*p ⇒ proporzionale a p (tasso di page fault) • p=1/1000 ⇒ eat=25microsec ⇒ 250 volte più lento di ma 21 10.3 Prestazioni della paginazione su richiesta • Se vogliamo un degrado < 10%, allora p deve essere tale che 110 > 100+25*106 *p 10 > 25*106 *p p < 0.4* 10-6 → 1 page fault ogni 2.500.000 accessi in memoria, cioè 1 page fault ogni 106 istruzioni circa 7 22 10.3 Prestazioni della paginazione su richiesta ⇒ il page fault ratio deve essere molto molto basso altrimenti il throughput della macchina si abbassa troppo • Memoria di swap: Occorre rendere velocissimo l'I/O verso BS. • Si può ottenere mediante: – pagine grandi – strutture di accesso al disco molti più semplici di quelle del file system 23 10.3 Prestazioni della paginazione su richiesta • Può convenire copiare l'eseguibile interamente in area di swap prima di iniziare l'esecuzione – tempo di start lungo – maggiore velocità nella paginazione – maggiore area di swap • Alternativa per limitare l'area di swap: – le pagine eseguibili sono richieste direttamente dal file system – se devono essere rimpiazzate, sono sovrascritte direttamente, perché non sono state modificate 24 10.3 Prestazioni della paginazione su richiesta ⇒ avvio molto più veloce del programma ⇒ esecuzione più lenta che nel caso della copiatura completa in area di swap • Terza via: – le pagine di eseguibile si caricano direttamente da file system – si copiano in area di swap quando si devono rimpiazzare 8 25 10.3 Prestazioni della paginazione su richiesta – avvio veloce – esecuzione più veloce quando il programma riusa la sua località – usato in BSD Unix 26 10.4 Rimpiazzamento delle pagine • Se ci fosse sempre una pagina libera, una pagina sarebbe caricata in memoria una sola volta nell'esecuzione del programma • La richiesta di pagine di un programma cambia (anche se lentamente) e può aumentare nel tempo → se non abbiamo più pagine libere scopriamo che abbiamo sovrallocato la memoria 27 10.4 Rimpiazzamento delle pagine • La situazione non è improbabile, se vogliamo usare il più possibile la memoria fisica • La situazione deve essere gestita! • Il SO si accorge del problema perché non trova nessun frame su cui caricare la pagina richiesta dalla trap. 9 28 10.4 Rimpiazzamento delle pagine 29 10.4 Rimpiazzamento delle pagine • Cosa può fare? – uccidere il processo che ha dato page fault: pessima soluzione! – fare swap-out del processo che ha dato page fault, liberare tutte le sue pagine e ridurre così il livello di multiprogrammazione: non male a volte (vedremo poi) – rimpiazzare (togliere) una pagina a qualcuno 30 10.4 Rimpiazzamento delle pagine • Cerchiamo una pagina "non in uso" e la portiamo su BS, liberando così il frame • Carichiamo in questo frame la pagina richiesta • Sistemiamo la PT del processo • Rimettiamo Running il processo 10 31 10.4 Rimpiazzamento delle pagine 32 10.4 Rimpiazzamento delle pagine • Il tempo di servizio del page fault raddoppia (due copiature di pagina)! • Se la pagina vittima è "pulita" (non modificata), abbiamo già una copia in BS → evitare di copiare in BS ⇒ Hardware deve dirmi se la pagina è pulita o meno, con un dirty bit nella PT ⇒ Salviamo su BS solo se il dirty bit è a 1 10.4 Rimpiazzamento delle pagine 33 • Notare: – Il rimpiazzamento è essenziale per permettere l'esecuzione di programmi più grandi della MP! ⇒ 2 problemi: – 1. Allocazione dei frame: quanti ne diamo a ciascun processo? – 2. Rimpiazzamento delle pagine: quale frame deve essere riutilizzato? Quale la pagina vittima? • Sono due algoritmi importantissimi! 11 34 10.5 Algoritmi di rimpiazzamento • Vorremmo quello che provoca il tasso di page fault minore • Vanno valutati su sequenze (stringhe) di riferimenti in MP – stringhe generate artificialmente – stringhe generate dall'esecuzione di programmi reali – stringhe molto lunghe – interessa solo l'accesso alla pagina, non il dettaglio del suo interno 35 10.5 Algoritmi di rimpiazzamento – accessi immediatamente successivi nella stessa pagina "valgono" come 1 solo (non possono dare ulteriori page fault, circa!) • Sapere quanti frame sono disponibili per il processo: – tale limite non è deciso dall'algoritmo di rimpiazzamento. – Rimpiazzamento all'interno delle pagine del processo 36 10.5.1 Algoritmo FIFO • Rimpiazzare la pagina più vecchia in MP → tenere una coda dell'arrivo delle pagine in memoria • Semplicissimo ma non sempre buono, perché la pagina più vecchia può essere: – una pagina del codice di inizializzazione (OK!) – una pagina con variabile inizializzata all'inizio ma molto usata (KO!) 12 37 10.5.1 Algoritmo FIFO • Anche il cattivo rimpiazzamento è comunque corretto: aumenta solo il tasso di page fault 38 Anomalia di Belady • Aumentando i frame possono aumentare i fault! • Stringa di riferimenti: 1234125112345 – Variamo il numero di frame concessi al processo 14 12 # page faults 10 8 6 4 2 0 1 2 3 4 # frames 5 6 7 39 10.5.2 Algoritmo ottimo • Che non soffra dell'anomalia di Belady • Che produce il numero minimo di page fault (a parità di frame disponibili) • OPT (o MIN): Sostituire la pagina che non verrà usata per più tempo • Problema: chi conosce il futuro? Problema indecidibile 13 40 10.5.2 Algoritmo ottimo • Esempio di applicazione dell’algoritmo ottimo alla sequenza precedente 41 10.5.3 Algoritmo LRU • Sostituire la pagina che non è stata usata da più tempo • LRU =:= Least Recently Used • Uguale a OPT, ma guardando all'indietro invece che in avanti: il passato è conosciuto! • Molto buono, ma ha problemi di implementazione efficiente 42 10.5.3 Algoritmo LRU • Esempio di applicazione dell’algoritmo LRU alla sequenza precedente 14 43 10.5.3 Implementazione LRU • Stack: – tenere uno stack dei numeri di pagina acceduti; – dimensione = numero di frame per processo – ad ogni accesso il numero di pagina viene portato (messo) in cima allo stack – la pagina in fondo allo stack è la LRU, da usare per rimpiazzamento – non viene mosso come uno stack; occorre una lista linkata doppia 44 10.5.3 Implementazione LRU • Contatori: – ad ogni pagina associato il clock al momento dell'uso – rimpiazzare la pagina con clock minore – molte scritture in memoria • Ambedue hanno bisogno di supporto hardware perché clock e stack vanno modificati ad ogni accesso in memoria! 45 Algoritmi di rimpiazzamento a stack • Le pagine in memoria con n frame sono un sottoinsieme di quelle con n+1 frame • LRU è uno stack algorithm • LRU, OPT e stack algorithms non soffrono dell'anomalia di Belady 15 46 10.5.4 Approssimazioni di LRU • Il supporto hw per LRU è costosissimo; senza supporto si può solo implementare FIFO • Reference Bit: settato da hw in PT quando la pagina è riferita: non fornisce un ordinamento sull'uso delle pagine ma permette di approssimare 47 Additional-Reference-Bits Algorithms • Registriamo il bit di riferimento a intervalli regolari (es. 100msec), azzeriamo e teniamo la storia degli ultimi (ad es.) 8 bit per ogni pagina • Considerati come unsigned int sono una approssimazione del clock: la pagina che ha il numero minore è la LRU 48 Additional-Reference-Bits Algorithms • La minima può non essere unica: ordinamento parziale – si rimpiazzano tutte; oppure – si usa una politica FIFO fra di loro • Se il numero di bit addizionali è zero (solo il reference bit), abbiamo l'algoritmo della Seconda Opportunità 16 49 10.5.4.2 Algoritmo della Seconda Opportunità • Si parte da un algoritmo FIFO, ma si usa un reference bit • Si considera la prima pagina in coda: se il reference bit della pagina è (ancora) 0, allora si rimpiazza • Se il bit della prima è a 1, allora si azzera il reference bit e le si da una Seconda Opportunità e si passa alla "seconda” della FIFO; e così via 50 10.5.4.2 Algoritmo della Seconda Opportunità • Se tutte hanno il reference bit a 1 allora si rimpiazza la più vecchia • Detto anche algoritmo dell'orologio, perché si può anche implementare scandendo circolarmente i frame del processo (senza tenere una coda FIFO esplicita) 51 10.5.4.3 Algoritmo della Seconda Opportunità Migliorato • Se l'hw fornisce reference e dirty bit, usiamo tutti e due (resettando il reference); abbiamo quattro classi di pagine: – (0,0) né usata né scritta: ottima da rimpiazzare – (0,1) non usata recentemente, ma modificata: meno buona – (1,0) usata recentemente, ma pulita: meglio non rimpiazzare – (1,1) usata recentemente e sporca: la peggiore da rimpiazzare 17 52 10.5.4.3 Algoritmo della Seconda Opportunità Migliorato • Scandiamo i frame con lo schema del clock, e sostituiamo la prima pagina della classe più bassa non vuota (può occorrere più di un giro!) • A differenza dell'algoritmo del clock semplice, preferiamo quelle pagine che non sono state modificate (meno I/O!) • Usato in MAC/OS (Macintosh) 53 10.5.5 Algoritmi basati su contatori • LFU: Least Frequently Used – Problema: una grande quantità di riferimenti non si "dimentica" mai – Soluzione: shift a destra ogni tanto → media a decadenza esponenziale • MFU: Most Frequently Used – Se ha pochi usi, è probabilmente stata portata in memoria da poco e quindi deve ancora essere usata – Ambedue costosi, poco usati, approssimano male OPT. 54 10.5.6 Algoritmo basato su Buffer di Pagine (Libere) • Usato in ausilio ad un algoritmo di rimpiazzamento, che sceglie la pagina vittima da rimpiazzare • Mentre la pagina vittima viene scritta su BS, la pagina richiesta viene letta su una pagina del pool di frame liberi tenuto a parte, in modo che sia resa disponibile al più presto 18 55 10.5.6 Algoritmo basato su Buffer di Pagine (Libere) • Quando la pagina vittima è stata scritta su BS, il suo frame viene aggiunto al pool dei frame liberi • Estensione 1: – Teniamo una lista di pagine sporche – Quando BS non ha da fare I/O, salviamo su BS una pagina sporca, che così ritorna pulita (reset del dirty bit) ⇒ aumenta la probabilità di trovare pagine pulite da rimpiazzare 10.5.6 Algoritmo basato su Buffer di Pagine (Libere) 56 • Estensione 2: – Tenere un pool di frame liberi, ma ricordare da quale pagina provengono – Se il fault riguarda una delle pagine che è nel pool delle libere si ri-usa subito; altrimenti si usa una delle libere – VMS/VAX usa FIFO per creare il pool di frame liberi • quando FIFO "sbaglia" si recupera facilmente la pagina dal pool • importante quando il reference bit non c'è oppure non è corretto (prime versioni del VAX) 57 10.6 Allocazione dei Frame • In un sistema monoprogrammato si alloca tutti quelli restanti • Ma con multiprogrammazione? – Come si suddividono i frame liberi tra i vari processi che vogliono eseguire ? – Si devono/possono tenere un numero minimo di frame liberi ? 19 58 10.6.1 Numero Minimo di Frame • Definito dal set di istruzioni della macchina: una pagina (o più) per l'istruzione, più una per ogni operando, considerando le forme di indirizzamento possibili (ad es. indirette) • PDP11: 2 per istruzione, 2 per op1, 2 per op2 → 6 pagine • IBM370: MVC: 2 per istruzione, 2 per op1, 2 per op2 → 6 pagine • EXEC MVC → 8 pagine 59 10.6.1 Numero Minimo di Frame • Riferimenti indiretti multipli: occorre mettere un limite al numero di indirettezze ammesse • Ma quale è il numero giusto fra il mio e tutta la memoria? 60 10.6.2 Algoritmi di Allocazione • Parti uguali: m frame disponibili, n processi → m/n pagine per processo. E qualcuna tenuta sempre libera come buffer • Alternativa: ad ogni processo secondo le sue "necessità" ⇒ allocazione proporzionale alla dimensione massima del processo. • Sia si la dimensione della memoria virtuale del processo pi • Sia m il numero totale di frame disponibili 20 61 10.6.2 Algoritmi di Allocazione • Se S=Σ si , allochiamo ai = si /S*m frames, arrotondato all'intero e non meno del minimo per l'architettura • In ambedue i casi l'allocazione cambia con il livello di multiprogrammazione • Non tiene conto della priorità di un processo! ⇒ usare una combinazione di dimensione e priorità 62 10.6.3 Allocazione Locale o Globale • Dove va a prendere i frame l'algoritmo di rimpiazzamento? • Globale: sceglie la vittima fra tutti i frame della MP (escluso in genere il SO) – può portare via il frame ad un processo diverso da quello che ha generato il page fault • Locale: sceglie la vittima fra i frame del processo che ha generato page fault – numero di frame per processo costante 63 10.6.3 Allocazione Locale o Globale • Problema con il globale: – comportamento diverso a seconda dei processi con cui si convive in MP – aumentando la priorità ad un processo gli si assegnano anche più pagine • Problema con il Locale: – se si danno troppe (relativamente) pagine ad un processo, si ha un throughput basso perché gli altri paginano molto 21 64 10.6.3 Allocazione Locale o Globale • Il rimpiazzamento globale da in genere un throughput maggiore e ammette livelli molto variabili di multiprogrammazione • Viene in genere preferito per sistemi time sharing 65 10.7 Thrashing • Se il numero di pagine per un processo scende al di sotto del minimo architetturale → swapout del processo • swap-out/in è necessario come scheduling intermedio della CPU (regolatore della multiprogrammazione) • Se le pagine per un processo sono comunque poche, si dovrà sostituire una pagina che userà fra poco, facendo subito fault, e così via 66 10.7 Thrashing • Se il rimpiazzamento è globale, il processo gira poco e gli verranno "prese" delle pagine da altri che hanno più pagine • Alla fine tutti i processi sono attivissimi a rubarsi pagine l'un l'altro, per fare page-fault subito dopo! • Questo fenomeno si chiama THRASHING 22 67 10.7 Thrashing 68 10.7.1 Cause del thrashing • Esempio concreto dei primi SO: – Utilizzo di CPU troppo basso? ⇒ Aumentare il livello di multiprogrammazione, aggiungendo un nuovo processo • Si tolgono pagine ai processi già in memoria – i processi aumentano il page fault, la coda del device di swap aumenta, la RQ si accorcia o si svuota 69 10.7.1 Cause del thrashing ⇒ utilizzazione della CPU diminuisce ⇒ scheduler carica in memoria un altro processo! • Nei sistemi time-sharing, il ciclo perverso è costituito dagli utenti, che lanciano altri programmi senza attendere la fine di quelli già lanciati 23 70 Come combattere il thrashing • Diminuire il livello di multiprogrammazione! • Usare una politica di rimpiazzamento locale • Dare ad ogni processo le pagine necessarie perché lui non vada in thrashing • Modello della località dell'esecuzione di un processo: – nell'esecuzione un processo si muove da una località ad un'altra – Una località è un insieme di pagine che vengono usate attivamente assieme 71 Come combattere il thrashing • Un programma è in genere costituito da numerose località, che possono essere sovrapposte • L'esecuzione di un processo cambia località lentamente • Le località sono legate alle chiamate di funzioni, alla struttura in moduli di un programma, e alle strutture dati usate dal programma 72 Come combattere il thrashing • Notare: – Le cache funzionano per lo stesso motivo! • Strategia: – assegnare ad ogni processo un numero di pagine tale da poter contenere la località del programma 24 73 10.7.2 Modello del Working-Set (WS) • Basato sull'ipotesi di località • Usiamo un parametro ∆ = working-set window = i più recenti ∆ riferimenti a pagine – WS è l'insieme delle pagine in ∆ – WS è una approssimazione della località del programma 74 10.7.2 Modello del Working-Set (WS) • Come scegliamo ∆? – Troppo piccolo non si vede la località – Troppo grande prende più località – Se ∞ → WS = dimensione del programma • Se WSS i è il WS di ogni processo, D=Σ WSS i è la richiesta totale di pagine – se D > m si ha thrashing 75 10.7.2 Modello del Working-Set (WS) • Il SO misura WSS i – se D>m sospende un processo (swap-out) liberando le sue pagine – se D<m fa swap-in di un processo sospeso, o ne avvia un altro • Problema: misurare WSS i – Approssimazione con timer interrupt e reference bit – Poco preciso e costoso 25 76 10.7.3 Frequenza di page fault • Thrashing è troppi page fault • Se la frequenza è alta vuol dire che il processo ha bisogno di pagine; • Se è bassa che ha troppe pagine • Metodo adattativo – Sospendere un processo se tutti mostrano di avere bisogno di pagine 77 10.7.3 Frequenza di page fault 78 10.8.1 Pre-paginazione • Problema: alto tasso di fault quando il processo parte oppure ritorna dopo swapout (ancora più importante, perché succede più volte) • Soluzione per swap-in: ricordare il workingset e riportarle tutte in MP prima di mettere Running il processo 26 79 10.8.1 Pre-paginazione • Non tutte saranno ri-usate. Se 0≤α≤1 sono ri-usate – risparmiamo α page fault – pre-paginiamo (1-α) inutili – se α è vicino a zero perdiamo – se α è vicino a 1 vinciamo 80 10.8.2 Dimensioni della pagina • Sempre potenze di 2; ma quanto grandi? • Pagine piccole implicano: – PT grandi – meno frammentazione interna – peggiore throughput di BS perché seek e latenza sono fissi e grandi rispetto al tempo di trasferimento – si individua la località più precisamente → meno I/O 81 10.8.2 Dimensioni della pagina – si aumentano i page fault (per prendere la località) → ogni page fault ha un costo fisso → non buono • La diminuzione del costo della MP spinge a pagine grandi 27 82 10.8.3 Struttura del programma • Il modo di accedere ai dati (deciso dal programma) può aumentare enormemente i page fault • Es: accesso agli array in modo contrario alla disposizione in memoria • Stack ha una buona località • Hash table pessima • Separare codice (read-only) dai dati (ci pensa il compilatore) aiuta 83 10.8.3 Struttura del programma • Non mettere una routine attraverso il confine di pagina; mettere nella stessa pagina routine che si chiamano a vicenda • Il programmatore mette tali routine nello stesso modulo e il linker-loader evita i confini di pagina e le impacca in modo da ridurre i riferimenti inter-pagina • Il linguaggio di programmazione influenza i page-fault: C e Pascal sono meglio di Lisp o Prolog 84 10.8.4 I/O Interlock • I/O è più efficiente se direttamente sulla memoria dell'utente (DMA) → le pagine interessate devono essere bloccate (locked) in MP durante la permanenza del comando in cosa e I/O • Lock bit per evitare rimpiazzamento. 28 85 10.8.4 I/O Interlock • Utile anche per – evitare rimpiazzamento di una pagina appena portata in memoria – pagine condivise da tanti processi – "aumentare" le prestazioni di un processo • Locking deciso dall'utente è un problema nei sistemi multi-user ⇒ solo "suggerimenti" per il SO 86 10.8.5 Elaborazioni Real-Time • La memoria virtuale è l'antitesi del real-time • Hard real-time mai con memoria virtuale • Soft real-time deve permettere "suggerimenti" di lock o lock stretti per processi privilegiati ⇒ se abusato, questo meccanismo degrada la prestazione degli altri processi 87 10.9 Segmentazione su Richiesta • Richiede meno supporto hardware • È un'approssimazione della paginazione • Se i segmenti venissero riempiti "oculatamente" dagli utenti (non lo fanno mai!) potrebbe anche essere meglio della paginazione 29 88 10.9 Segmentazione su Richiesta • Es. OS/2 per Intel 80286 con supporto per segmentazione soltanto – come per la paginazione, ma a livello segmento – 80286 ha accessed bit – syscall per dire al SO quali segmenti no sono più utili o devono restare in memoria – compattazione della memoria contro la frammentazione esterna 30