Esercizio - Programmi che scorrono array, stringhe di riferimenti e page fault (eserciziario, esercizi 50, 73 e 77)
In questa pagina 5
Testo (eserciziario del corso di Sistemi Operativi, Ing. Informatica UniPD).
- Esercizio 50. Matrice
int A[100][100], con la posizioneA[0][0]alla locazione 200 di una memoria paginata con 3 pagine di 200 B. Un valoreintoccupa 1 B; le pagine sono inizialmente vuote e il processo (il cui codice occupa esattamente 200 B) eseguefor (i = 0; i < 100; i++) for (j = 0; j < 100; j++) A[i][j] = 0;. Quanti page fault con LRU? (Ogni pagina contiene 200 elementi della matrice.) - Esercizio 73. Il sistema di paginazione assegna 3 frame da 512 B a ogni processo. Programma:
#define N 512,int A[N], C[N],for (i = 1; i <= 2; i++) for (j = 0; j < N/2; j++) A[i*j] = A[2*i] + C[2*j];. Un intero è rappresentato con 2 B. Gli array e occupano 1024 B ciascuno, in 2 pagine da 512 B:A[0..255]pagina 0,A[256..511]pagina 1,C[0..255]pagina 2,C[256..511]pagina 3. (1) Stringa dei riferimenti alle pagine della memoria. (2) Tabella delle pagine al termine della procedura con avvicendamento (i) FIFO, (ii) LRU. - Esercizio 77. 3 frame da 512 B a ogni processo, algoritmo LRU. Programma:
#define N 512,int a[N],for (i = 0; i < N/2; i++) a[i] = a[2*i] + a[N-i-1];. (a) Se un intero è di 4 B, quanti page fault? (b) Se il tempo medio di servizio di un page fault è di 25 ms e l'accesso alla memoria 100 s, qual è il tempo di accesso medio della paginazione su richiesta? Le pagine sono da 512 B e ogni intero è di 4 B (128 elementi per pagina):a[0..127]pagina 0,a[128..255]pagina 1,a[256..383]pagina 2,a[384..511]pagina 3.
Il metodo
- Si scrive l'ordine in cui il programma tocca la memoria, istruzione per istruzione: di solito prima le letture (nell'ordine di valutazione) e poi la scrittura.
- Per ogni indice, si calcola la pagina: (o, per le matrici, la posizione lineare in memoria).
- Si comprime la stringa dei riferimenti (accessi consecutivi alla stessa pagina non contano come nuovi fault) e si applica l'algoritmo di sostituzione.
Esercizio 50 (matrice per righe, LRU, 3 frame)
La matrice è memorizzata per righe: A[0][0], A[0][1], …, A[99][99]. Ha elementi da 1 B e comincia alla locazione 200: occupa le locazioni da 200 a 10 199, cioè pagine, a partire dalla pagina 1 (la pagina 0, le locazioni 0-199, contiene il codice).
Ad ogni iterazione si accede al codice (pagina 0, per leggere l'istruzione) e a un elemento di A. Poiché ad ogni passo si riferisce la pagina 0, questa è sempre la più recente: non viene mai scelta come vittima. Delle altre due pagine si alternano i due frame:
- i primi 200 azzeramenti (
A[0][0]…A[1][99], righe 0 e 1) accedono alla pagina 1; - i successivi 200 alla pagina 2, e così via: ogni 200 elementi si cambia pagina.
Page fault: 1 per caricare il codice (pagina 0) e 50 (una per ciascuna delle 50 pagine della matrice, quando vi si accede la prima volta), in totale
La pagina matrice usata meno di recente è quella vecchia, quindi la sostituzione toglie sempre una pagina già finita di scorrere. Il valore è lo stesso (51) per la soluzione del corso.
(Se la matrice fosse scandita per colonne, for j … for i …, ogni elemento sarebbe in una pagina diversa dal precedente: salti di 100 posizioni, due righe ogni pagina: molti più fault; il caso esteso è nel laboratorio 7.)
Esercizio 73
(1) Stringa dei riferimenti. Ogni iterazione calcola A[i*j] = A[2*i] + C[2*j] e quindi legge A[2*i], legge C[2*j] e scrive A[i*j].
A[2*i]: con èA[2](pagina 0); con èA[4](pagina 0).C[2*j]: per (pagina 2), per (pagina 3).A[i*j]: con èA[j], indice : pagina 0. Con èA[2j]: pagina 0 per , pagina 1 per ().
| riferimenti per iterazione | iterazioni | ||
|---|---|---|---|
| 1 | 0-127 | 0 2 0 | 128 |
| 1 | 128-255 | 0 3 0 | 128 |
| 2 | 0-127 | 0 2 0 | 128 |
| 2 | 128-255 | 0 3 1 | 128 |
Stringa compressa: .
(2) Tabella delle pagine. I frame sono 3.
FIFO (5 fault):
- primo accesso alla pagina 0: fault; poi la pagina 2: fault ();
- : la pagina 3 entra nel terzo frame: fault. Ora i frame hanno 0, 2, 3 (in ordine di caricamento: 0 la più vecchia);
- : la pagina 1 è nuova: fault; FIFO toglie la 0 (la più vecchia);
- subito dopo la pagina 0 serve di nuovo (iterazione ): fault; FIFO toglie la 2.
Totale 5 fault. Alla fine in memoria: pagine 1, 0, 3 (la 2 non c'è più).
LRU (4 fault): come FIFO fino a . Qui si deve inserire la 1; nella stessa iterazione le pagine 0 (A[4]) e 3 (C[256]) sono appena state riferite, quindi la meno recente fra 0, 2, 3 è la 2: LRU toglie la 2 e non la 0, e non c'è il fault aggiuntivo. Totale 4 fault. Alla fine in memoria: pagine 0, 1, 3.
La differenza è in una pagina (la 0) riferita continuamente: FIFO guarda solo quando è stata caricata (per prima), LRU guarda che è sempre in uso.
Esercizio 77
(a) Gli elementi a[0..127] sono nella pagina 0, a[128..255] nella 1, a[256..383] nella 2, a[384..511] nella 3. Ogni iterazione riferisce a[2*i], a[N-i-1] e scrive a[i]: tre riferimenti, in totale riferimenti.
a[2*i] |
a[N-i-1] |
a[i] |
|
|---|---|---|---|
| 0-63 | pagina 0 () | pagina 3 () | pagina 0 |
| 64-127 | pagina 1 () | pagina 3 | pagina 0 |
| 128-191 | pagina 2 () | pagina 2 () | pagina 1 |
| 192-255 | pagina 3 () | pagina 2 () | pagina 1 |
Con LRU e 3 frame:
- : la pagina 0 (fault), la 3 (fault);
- : la pagina 1 (fault): frame 0, 3, 1; da qui fino a 127 si usano 0, 1, 3;
- :
a[256]è nella pagina 2 (fault): si toglie la meno recente, la 1; ma la scritturaa[128]della stessa iterazione richiede subito la pagina 1, quindi un altro fault, che toglie la meno recente fra 0, 3, 2, cioè la 3; - : la pagina 3 (fault, si toglie la 0 non più usata).
In totale 6 page fault, e riferimenti validi (senza fault). (Il risultato coincide con la soluzione del corso: 6 fault e 762 riferimenti.)
(b) Tempo medio di accesso con paginazione su richiesta:
(La soluzione scrive s.)
Errori tipici
- Dimenticare l'accesso al codice nell'esercizio 50: la pagina 0 occupa un frame e si carica una volta.
- Compressione sbagliata della stringa: accessi consecutivi alla stessa pagina sono hit, non nuovi riferimenti da ripetere.
- Calcolare la pagina di
A[i*j]senza distinguere e nell'esercizio 73. - Non scrivere la scrittura
a[i]fra i riferimenti.
Versione ripasso
Metodo. Elencare gli accessi (letture poi scrittura), calcolare la pagina di ognuno, comprimere gli accessi consecutivi alla stessa pagina, applicare FIFO/LRU.
50. Matrice 100x100 byte da 200 (50 pagine), pagina 0 con il codice, 3 frame, LRU: la pagina 0 è sempre la più recente; ogni 200 elementi cambia pagina: fault.
73. A[i*j]=A[2*i]+C[2*j], pagine 0, 1 () e 2, 3 (). Riferimenti: . FIFO: 5 fault (la 1 toglie la 0, poi la 0 toglie la 2); finale 1, 0, 3. LRU: 4 fault (la 1 toglie la 2); finale 0, 1, 3.
77. a[i]=a[2*i]+a[N-i-1], 128 interi per pagina, 768 riferimenti, LRU 3 frame: 6 fault, 762 senza fault. ms.
Passaggi. 73: letture A[2*i], C[2*j], scrittura A[i*j]; pagina ; , : A[2*j] in pagina 1. Frame dopo , : 0, 2, 3. FIFO: 1 toglie 0 (la più vecchia), poi 0 toglie 2 5 fault, finale 1, 0, 3. LRU: 1 toglie 2 4 fault, finale 0, 1, 3. 77: 768 riferimenti; pagine 0, 3, 0; 1, 3, 0; 2, 2, 1; 3, 2, 1; fault a (pagine 0 e 3), (pagina 1), (pagine 2 e di nuovo 1), (pagina 3) ; ms. 50: matrice da 10 000 byte a partire da 200: 50 pagine (1-50) più il codice: 51 fault.
Errori tipici: dimenticare il codice (ex. 50); stringa non compressa; pagina di A[i*j] senza distinguere ; scrittura dimenticata.