I sistemi operativi – La gestione della memoria

 

La memoria è una delle tre componenti fondamentali dell’elaboratore. Essa è direttamente legata alle applicazioni ed ha rappresentato per molto tempo, per la sua ristrettezza, un problema allo sviluppo dei sistemi. Le prime memorie erano addirittura fabbricate a mano, infilando negli anellini di ferrite i fili che servono a portare la corrente necessaria alla loro magnetizzazione o a leggerne lo stato. Le memorie di tipo solido, a componenti integrati, appaiono solo agli inizi degli anni 70, e comunque con una densità ed un costo sempre decisamente elevato.

D’altra parte i programmi, per essere eseguiti, devono essere caricati completamente in memoria  ed essere accessibili alla CPU. Per di più la portabilità delle applicazioni da un sistema ad un altro presuppone che i sistemi coinvolti abbiano memoria sufficiente per poterli contenere. Si è dunque posto il problema di svincolare le applicazioni dalla dimensione della memoria, quindi di permettere una portabilità ed uno sviluppo che potesse procedere senza condizionamenti contingenti. Viene introdotta la cosiddetta “memoria virtuale”.

Se noi analizziamo l’uso che un programma fa della memoria, possiamo facilmente intuire che non tutte le parti della memoria sono utilizzate allo stesso modo. Possiamo distinguere in un programma una parte che serve normalmente ad inizializzare le aree di lavoro ed a stabilire le connessioni per gli accessi ai dati esterni e che viene eseguita una sola volta. Vi è poi il ciclo ripetitivo di elaborazione che viene eseguito più volte, tante quanti sono i dati da trattare ed infine una parte finale, anch’essa eseguita una sola volta, che chiude l’elaborazione. Nella parte centrale inoltre vi saranno parti eseguite più frequentemente ed altre meno.

Se noi dividessimo il programma in piccole parti uguali in dimensione(le chiameremo “pagine”) e ordinassimo queste pagine in funzione della loro frequenza di accesso, troveremmo per prime alcune pagine con un’alta frequenza di accesso e via via le altre con una frequenza di accesso sempre decrescente. Statisticamente possiamo rilevare che per la grande maggioranza dei programmi abbiamo un addensamento notevole su poche pagine ad alta frequenza di accesso con un accesso molto basso su un’alta percentuale di pagine. Il numero delle pagine, o meglio la dimensione delle pagine più frequentemente accedute si definisce “working set” di un programma.

Ora immaginiamo di poter introdurre una memoria, la memoria virtuale, che per le applicazioni  a tutti gli effetti possa essere una memoria con un qualcosa che possa mettere a disposizione della CPU, via via che servono, le pagine di memoria in quel momento richieste e tenere su un supporto esterno, la memoria ausiliaria (per esempio un disco), le pagine in quel momento non utilizzate.

Poiché il working set di un programma è più piccolo della dimensione del programma stesso, questo ci permette di avere una memoria reale (quella hardware) più piccola di quella virtuale, o meglio, di poter mettere a disposizione della applicazioni una memoria virtuale più grande di quella effettivamente installata. Il meccanismo di corrispondenza delle pagine richiede ovviamente tempo e può essere parte della CPU stessa: in questo caso si toglie una parte di potenza che potrebbe essere utilizzata per eseguire istruzioni di programma. Questa potenza è un puro costo e occorre trovare e realizzare un meccanismo che possa trovare il giusto bilanciamento fra dimensione della memoria virtuale e memoria reale per ridurre questo spreco al minimo.

La parte che traduce gli indirizzi da virtuali a reali è quasi sempre direttamente cablata in circuiti hardware, mentre la parte del sistema operativo che gestisce la memoria è diventata:

·        Il gestore della memoria virtuale. Esso ha il compito di gestire l’uso della memoria assegnandone la proprietà,  gestendo memoria libera ed impegnata.

·        Il gestore della memoria reale. Questo ha il compito di assegnare, quando necessario, ad ogni pagina che deve essere caricata in memoria, una corrispondente parte di memoria reale (frame). Facendo una fotografia della memoria reale troviamo, l’una accanto all’altra, pagine di programmi diversi che compongono il working set  delle applicazioni.

·        Il gestore della memoria ausiliaria. Esso gestisce il trasferimento delle pagine fra la memoria reale e il supporto esterno su elementi corrispondenti (slot). Questa attività viene definita “paginazione” e i file esterni utilizzati a questo scopo sono chiamati appunto “di paginazione” o “di swap”.

All’interno del sistema operativo troviamo un altro supervisore, il “page supervisor”, che comprende quella parte di logica che deve eventualmente innescare il processo di paginazione e una serie di componenti che devono in generale gestire l’ottimizzazione del rapporto fra memoria virtuale e memoria reale per mantenere la paginazione ad un livello tollerabile. La paginazione cresce al crescere del rapporto fra memoria virtuale utilizzata e memoria reale disponibile e lo fa in maniera esponenziale fino ad arrivare ad un punto in cui il sistema di fatto dedica gran parte delle sue risorse a questa attività (situazione di “trashing”).

Fortunatamente nel corso degli anni la memoria reale è diventata sempre meno costosa e sempre più capace, fino ad arrivare oggi ad essere tutto sommato la parte meno costosa. Di conseguenza la paginazione è scesa in generale a livelli trascurabili e non rappresenta più l’elemento più critico per l’ottimizzazione del sistema. Non dimentichiamo però che comunque le applicazioni sono cresciute in modo considerevole: la funzione di memoria virtuale è utilizzata normalmente ancora oggi e lo sarà presumibilmente ancora in futuro. La capacità di indirizzamento virtuale è oggi arrivata  a 48 e 63 bit, mentre la memoria reale è nell’ordine dei 36 bit (decine di Gigabytes): come vedete il divario è ampio e continuerà ad esserlo ancora per molto.

Nell’equilibrio delle parti oggi torna ad essere delicato il rapporto fra potenza disponibile e quantità dei dati da gestire, non tanto per le dimensioni dei supporti esterni disponibili ma soprattutto per la capacità di accesso ai dati stessi, che, per la maggior parte, risiedono su supporti esterni e con una velocità di accesso ancora estremamente bassa (circa 6 ordini di grandezza di differenza fra un supporto di memoria reale e uno di memoria esterna).

La gestione della memoria esterna sarà l’argomento del prossimo intervento.

 

Al Mariani

 

Computer amico mio