Gestione della memoria
La memoria centrale
Introduzione
La memoria è uno strumento fondamentale per lo svolgimento delle operazioni di un calcolatore moderno, formato da un vettore di byte (o parole) ciascuno avente il proprio indirizzo. La CPU preleva le istruzioni in base al valore contenuto nel PC, e queste istruzioni possono richiedere altre operazioni di load (letture) o store (scritture) in specifici indirizzi della memoria.
Dispositivi essenziali
Le uniche zone alle quali la CPU può accedere sono la memoria centrale e i registri di memorizzazione, per cui i dati su cui lavorare e le istruzioni da eseguire dovranno essere caricati in una di queste zone prima di poter essere utilizzati. Solitamente, i registri sono accessibili per un ciclo di clock, anche se molti processori sono in grado di svolgere anche più di un’istruzione a ciclo. Però, se l’accesso alla memoria richiede più di un ciclo di clock, allora la memoria entra in stallo, in quanto l’istruzione in esecuzione è carente di alcuni dati necessari al suo compito. Per risolvere questo problema si può interporre una memoria veloce, o buffer, detta cache, tra la CPU e la memoria centrale, la quale è in grado di conciliare le due diverse velocità.
Un altro aspetto molto importante, oltre alla velocità, è la protezione del SO dall’accesso dei processi utente. Bisogna garantire che ciascun processo abbia un proprio spazio di memoria separato. Un metodo per la protezione è quello che fa uso di due registri, i quali possono essere caricati solo dal SO mediante un’istruzione speciale. Questi registri sono:
- Il registro base contiene il più piccolo indirizzo legale della memoria fisica.
- Il registro limite determina la dimensione dell’intervallo ammesso.
Per mettere in atto la protezione tramite questo metodo, la CPU mette a confronto qualsiasi indirizzo generato in modalità utente con i valori contenuti nei due registri. Se l’indirizzo è compreso tra base e limite allora si può accedere in memoria, altrimenti viene inviato un segnale di eccezione che restituisce il controllo al sistema operativo. In questo modo si impedisce a qualsiasi programma utente di alterare il codice o le strutture dati.
Associazione degli indirizzi e spazi degli indirizzi
Ciascun programma, prima di essere eseguito, risiede nel disco sotto forma di file binario. Per entrare in esecuzione, un programma deve essere caricato in memoria e inserito all’interno di un processo. L’insieme dei processi presenti nel disco che sono in attesa di essere caricati in memoria per l’esecuzione forma la coda d’ingresso, dal quale vengono scelti di volta in volta i processi da eseguire. Una volta che un processo termina, il suo spazio si libera.
Nella maggior parte dei casi, prima di essere eseguito, un programma utente deve attraversare diversi stadi (alcuni facoltativi) nei quali gli indirizzi sono rappresentati in maniera differente. Gli indirizzi del programma sorgente sono simbolici, il compilatore poi associa questi indirizzi simbolici a indirizzi rilocabili, mentre l’editor dei collegamenti fa corrispondere agli indirizzi rilocabili gli indirizzi assoluti. Ogni associazione rappresenta un’associazione tra uno spazio degli indirizzi e un altro.
L’associazione di istruzioni e dati a indirizzi di memoria si può eseguire in qualsiasi fase:
- Compilazione: si può generare il codice assoluto solo se si sa dove risiederà il processo in memoria centrale.
- Caricamento: se nella fase di compilazione non è nota la posizione del processo in memoria allora viene generato un codice rilocabile. Si ritarda l’associazione fino alla fase di caricamento.
- Esecuzione: se durante questa fase un indirizzo può essere spostato da un segmento all’altro, si deve ritardare l’associazione fino all’esecuzione.
Un indirizzo può essere:
- Logico, viene generato dalla CPU. Nella fase di esecuzione sono detti indirizzi virtuali.
- Fisico, visto dall’unità di memoria e quindi caricato nel registro dell’indirizzi di memoria (MAR).
Le fasi di compilazione e caricamento generano indirizzi logici e fisici identici, mentre nella fase di esecuzione non corrispondono. Si definiscono due spazi degli indirizzi:
- Spazio degli indirizzi logici, insieme degli indirizzi logici generati da un programma.
- Spazio degli indirizzi fisici, insieme degli indirizzi fisici corrispondenti a quelli logici.
L’associazione nella fase di esecuzione degli indirizzi virtuali a quelli fisici è svolta dall’unità di gestione della memoria (MMU). Nel metodo che fa uso della MMU, il registro di base prende il nome di registro di rilocazione, il cui valore viene sommato all’indirizzo virtuale (logico) in modo da ottenere quello fisico.
Caricamento dinamico
Il caricamento dinamico carica una procedura solo quando essa viene richiamata, migliorando così l’utilizzo della memoria. Quando il programma in esecuzione richiama una procedura, si controlla che quest’ultima non sia già stata caricata, altrimenti si richiama il caricatore di collegamento rilocabile per eseguire il caricamento, il controllo passa alla procedura appena richiamata e viene aggiornata la tabella degli indirizzi. Il SO non interviene durante questa operazione. Il vantaggio del caricamento dinamico è che non si caricano le procedure fino a quando non siano necessarie, ed è quindi utile quando si devono adoperare grandi quantità di codice poco frequenti.
Collegamento dinamico e librerie condivise
Il funzionamento del collegamento dinamico è analogo a quello del caricamento, ma si riferisce appunto al collegamento delle librerie. Questo metodo si utilizza soprattutto per le librerie di sistema. In ogni programma è presente una porzione di codice, detta stub, che indica come localizzare la procedura di libreria o come caricare la libreria stessa se non è presente.
-
Gestione della memoria virtuale
-
Gestione della Qualità
-
Gestione della Qualità: Esercizi
-
Gestione aziendale