SO: Partizionamento della memoria e paginazione
INDICE:
- Utilizzo delle system call e protezione della memoria
- Partizionamento della memoria
- Partizionamento fisso
- Partizionamento fisso a code multiple
- Partizionamento fisso a singola coda
- La tecnica di overlay
- Partizionamento dinamico
- Come lavorare col partizionamento dinamico e la frammentazione della memoria
- Swapping dei processi e I/O Asincrono
- Cenni iniziali sulla paginazione di memoria
Utilizzo delle system call e protezione della memoria
Come già abbiamo detto durante lo startup in memoria viene riservata una regione in cui è caricato il codice del monitor e i moduli associati. Questi moduli aggiuntivi sono delle funzioni che possono essere utilizzate dagli applicativi e che in generale forniscono le parti d'uso comune per differenti applicazioni; sono le cosidette System Call.
Per quello che abbiamo detto è possibile ipotizzare che una applicazione possa fare delle chiamate verso il monitor utilizzando le system call messe a disposizione. In poche parole la stessa applicazione dovrebbe uscire dai limiti ad essa imposti dal criterio di protezione già detto, entrando nella regione del monitor (attraverso l'istruzione JUMP assembly di ogni macchina).
Un simile permesso, se accordato dal sistema, potrebbe far perdere il controllo della macchina dal monitor, che a conti fatti sarebbe soggetto al controllo da parte dell'applicazione che ne ha chiamato le routine.
Il problema viene aggirato collegando ad ogni system call dell'applicazione un fork a un piccolo modulo misto di asm/c che permette di generare al suo interno un trap e che di fatto regola i privilegi in maniera tale che il monitor non perda il controllo. Queste funzioni del monitor sono quindi accessibili tramite l'header specifico dell'OS (unistd.h in UNIX, simile per Windows) ma l'applicazione non può vedere ne operare sui dati e moduli definiti all'interno del monitor.
Partizionamento della memoria
Un sistema multiprogrammato bach permette, come abbiamo visto, di eseguire più applicazioni alla volta. La gestione delle aree di memoria ad esse riservate può avvenire secondo due tecniche distinte: il partizionamento fisso e quello dinamico della memoria.
Partizionamento fisso
La memoria di lavoro viene suddivisa in tanti blocchi di dimensione fissa (non modificabile). L'idea è quella di avere n partizioni ammissibili in grado di ospitare al più n processi contemporaneamente. Questo significa che il sistema operativo dovrà registrare le informazioni circa la zona di memoria associata ad ogni processo. Ci sono due differenti tipi di azioni per attivare nuovi applicativi o nel caso in cui un processo ne attivi un secondo.
- Partizionamento fisso con code multiple
Si può operare per code multiple in cui prima ancora di attivaare il processo si stabilisce a quale partizione deve afferire (con questa tecnica si ottimizza la partizione che deve usare cercando quale sia più adatta alla taglia del processo ed evitando così una frammentazione della memoria).Con questa tecnica però si ha che magari alcune partizioni siano senza processi (perchè troppo grandi o troppo piccole) mentre alte contengano troppi processi in attesa di essere eseguiti (ogni processo in coda deve attendere che il precedente sia stato esaurito per prenderne quindi il posto all'interno della partizione) portando così ad uno spreco di ram.Si ha quindi la frammentazione esterna (ovvero quella della coda) della ram.
- Partizionamento fisso a coda singola
Usando questa tecnica si mettono tutti i processi in una coda singola e si sceglie di volta in volta la partizione giusta a cui doverli associare. In questo modo poi il comportamento dipende dal tipo di coda e se è o no una coda con priorità: in quest'ultima magari un processo in coda che non può essere assegnato viene scalato indietro e quindi si passa al prossimo della coda, evitando i tempi morti dovuti all'attesa di una regione libera adatta.La tecnica generale è quella di creare comunque molte partizioni piccole e poche grandi in maniera tale che ci siano molti processi in uso (questo sistema è completamente integrabile con le tecniche di gestione memoria swap-in e swap-out).
La tecnica di overlay
Se il processo risulta essere più grande della partizione ammissibile (potrebbe addinittura richiedere l'intera ram) si può decidere di non eseguirlo oppure ricorrere ad una tecnica chiamata di overlay. L'overlay è a discrezione e completa implementazione del programmatore; si tratta di caricare e scaricare dalla memoria soltanto le parti del programma che sono necessarie sostituendole ai dati/moduli caricati precedentemente nella zona dedicata.

L'overlay deve essere gestito da un gestore di overlay implementato dal programmatore stesso dell'applicazione e soltanto i dati comuni e usati globalmente per l'applicazione devono rimanere in memoria. Questa tecnica come è facile capire è molto complicata perchè scaricamenti non necessari o errati possono portare a comportamenti del processo imprevedibili.
Il gestore dell'overlay è quindi la porzione di software che da il controllo al modulo chiamato caricando la porzione di memoria necessaria (mappa i riferimenti alle routine e ai piazzamenti). Il binding con questa tecnica può essere anche quello a tempo di compilazione (ma anche di caricamento attraverso la risoluzione da parte del loader e a tempo esecuzione).
Partizionamento dinamico
Nel partizionamento dinamico le zone di memoria sono create quando richiesto e della dimensione richiesta. Inizialmente la regione di memoria è libera con solo la partizione dedicata al monitor. Quando un processo ne fa richiesta, il monitor si occupa di indicare il range in cui va caricata.
Questa tecnica pone il problema del partizionamento della memoria (come è possibile vedere dalla figura) in cui quando un processo viene chiuso e la porzione di memoria liberata e riallocata alcune parti rimangono inusate e magari non usabili perchè troppo piccole per contenere altri processi.
Questo è un problema di frammentazione della memoria esterna (quella libera insomma diviene sempre più frammentata e quindi sempre meno utilizzabile).

Per ovviare a ciò il sistema operativo si occupa periodicamente di compattare di nuovo le partizioni in un blocco non frammentato, eseguendo lo spostamento delle diverse regioni in maniera contigua (si possono fare due compattazioni, on demand oppure periodicamente). Tuttavia questa operazione è permessa soltanto con un binding degli indirizzi a tempo di esecuzione (altrimenti i processi non possono essere spostati dalla memoria! gli indirizzi come abbiamo visto sono fissi); inoltre ha un costo molto elevato (ogni volta che sposto un processo il monitor dovrà caricare prendere ogni word/longword, caricala in un registro e quindi metterla nella nuova posizione, così per tutte le porzioni di memoria di cui è composto il processo).

Come lavorare col partizionamento dinamico e la frammentazione
Il problema dei costi di deframmentazione è stato affrontato secondo diverse scuole di pensiero: a seconda dell'algoritmo che si sceglie per costruire la partizione dinamica, si può fare in modo da gestire i fattori su quanto velocemente deve essere ricostruita la partizione (e farlo quindi il meno possibile e nel modo migliore).
Le partizioni libere sono chiamate memory hole. Esistono quindi tre schemi di allocazione di processi:
- first fit: i memory hole sono mantenuti in una lista con tutti i range delle memory hole. Appena arriva un processo l'OS sceglie dalla lista il primo che va bene (sufficentemente grande in modo da contenere il processo). Lo scorrimento della lista può essere fatto sempre dall'inizio o dall'ultima posizione. In questo caso il grado di complessità computazionale viene abbatuttoperchè prendo non si scorre l'intera lista (se non nel caso peggiore).
- best fit: viene scelto il m.hole più vicino alla taglia del processo. Qui la frammentazione esterna è ridotta però per avere un best fit devo scorrere tutti i memory hole possibili. Se ci sono quindi moltissimi memory hole la complessità di allocazione sale.
- worste fit: alloco il processo nel più grande memory hole possibili. In questo caso i memory hole residui sono più grandi dei precedenti. Anche la gestione del worste fit è costosa perchè devo scorrere o tutta la lista oppure mantenere una nuova struttura in grado di mantenere in memoria la locazione della zona più grande che di volta in volta rimane.
Swapping dei processi e I/O Asincrono
l'I/O asincrono significa che il processo esegue la chiamata di I/O ma non rimane in stato di blocco finchè l'I/O sia completo. Così mentre una parte del kernel legge il file l'applicazione può comunque continuare a fare altro.
L'utilizzo dello swapping (e quindi del fatto di poter caricare e scaricare porzioni o processi fuori e dentro la memoria di lavoro) non può funzionare se si usa L'I/O asincrono a livello di applicazione (e quindi il dato viene posto dentro la regione di memoria ad essa riservata: questo perchè se mentre il buffer legge lo swapping potrebbe portare fuori il processo per mettercene un altro portando così ad una incongruenza dati).
Il livello asincrono con swapping può essere applicato quindi solo a livello di sistema (le regioni riservate dal sistema operativo sono utilizzate per contenere il buffer e solo al loro termine passano l'handle al processo che le ha richieste).
Il sistema operativo fornisce questa funzione in maniera automatica che avviene in modo trasparente al programmatore.
Se l'applicativo richiede una quantità di byte che eccede la quantità di memoria che il sistema riserva il sistema può ritornare un errore alla system call notificandone l'impossibilità di esecuzione.
Cenni iniziali sulla paginazione della memoria
Lo schema a p. dinamiche è uno schema che rispetto al precedente ha molta flessibilità poichè il grado di multiprogramamzione è variabile (teoricamente infinito) e permette la compattazione della frammentazione. Tuttavia, come abbiamo appena visto, l'allocazione delle regioni di memoria e la compattazione non è così flessibile benchè ci siano modi per ridurne l'impatto.
E' stato quindi creato un nuovo modo di gestire la memoria, la paginazione. Paginare un processo significa prendere tutti i riferimenti logici e suddividere l'intervallo dei riferimenti in tante sottosezioni. Ciascuna di essere è denominata pagina.
La caratterisdtica è che tutte le pagine hanno la stessa taglia occupando una quantità uguale di memoria x bytes. L'idea è quella di prendere la memoria ram e pensarla dal punto di vista logico come formata da tante piccole sottosezioni di x bytes (memory frame).
Si alloca quindi una pagina in un memory frame evitando così il problema della frammentazione. Tutte le pagine coprono i relativi frame non avendo nessuna pagina vuota (o al massimo l'ultima). Ora è necessaria una struttura che mappa gli indirizzi logici e fisici alle relative pagina. La dimensione delle pagine và quindi studiata bene in modo tale che se rimane della frammentazione questa risulti trascurabile.
17-01-2007
About this page
You’re currently reading “SO: Partizionamento della memoria e paginazione,” an entry on malcom
- Published:
- 1.17.07 / 4pm
- Category:
- Blog Cafe
No comments
Jump to comment form | comments rss | trackback uriShow / Hide Comments