10. Memoria Virtuale 10. Memoria Virtuale 10.1 Le basi

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