Virtual Memory Subsystem in Linux Kernel 2.6 | Cerca per titolo, autore, parola chiave | ||||||||
Virtual Memory Subsystem in Linux Kernel 2.6 A.S.Sumant ,P.M.Chawan, January 2010. Il kernel 2.6 Linux impiega molte tecniche per aumentare la memoria disponibile, per andare incontro alle esigenze dell'impresa, che richiede di poter elaborare un numero sempre maggior di dati. Questo articolo sottolinea alcuni di questi cambiamenti intervenuti, quali il reverse mapping, l'uso di pagine di memoria più grandi, l'uso delle tabelle delle pagine nella high memory, la grande stabilità del gestore della memoria. Il memory management subsystem è una delle parti più importanti del sistema operativo. Sin degli albori dell'informatica, c'è sempre stato il bisogno di una quantità di memoria superiore a quella presente fisicamente in un sistema. Molte strategie differenti sono state sviluppate per superare queste limitazioni e la più efficace è la virtual memory. La memoria virtuale fa sì che il sistema sembri avere una quantità di memoria superiore a quella che effettivamente ha, permettendo così di condividere aree di memoria tra più processi. Linux supporta la memoria virtuale utilizzando il disco fisso come un'estensione della memoria RAM, accrescendo, quindi, la quantità di memoria utilizzabile. Il kernel copia il contenuto di un blocco di memoria attualmente non utilizzato nell'hard disk, liberando il blocco di memoria per altri processi. Quando dovesse essere nuovamente richiesto, il contenuto originale verrebbe ritrasferito dal disco fisso alla memoria RAM. Questo avviene in modo del tutto trasparente all'utente; i programmi in esecuzione sotto Linux vedono solo la maggiore quantità di memoria disponibile e non notano quei blocchi che, di tanto in tanto, risiedono su disco fisso. Nel Linux memory manager, le tabelle delle pagine (page tables) tengono traccia delle pagine di memoria fisica utilizzate da un processo, oltre a mappare le pagine virtuali di memoria con le pagine fisiche. Alcune di queste pagine potrebbero non essere utilizzate per lunghi periodi di tempo, rendendole ottimi candidati all'area di swap (su disco fisso). Tuttavia, prima di trasferirle su disco fisso, è necessario trovare ogni singolo processo che stia puntando a quella pagina di memoria, in modo da aggiornare il relativo record della page-table del processo. In Linux 2.4 kernel, questo potrebbe rivelarsi un incubo, visto che rende necessario attraversare le page tables di tutti i processi in esecuzione, al fine di stabilire se ogni singolo processo rimanda a quella pagina di memoria. Più il numero dei processi in esecuzione è alto, più cresce il lavoro per spedire in area di swap una pagina. Il Reverse mapping, o RMAP, venne implementato nel kernel 2.5 proprio per risolvere questo problema. Con il Reverse mapping, invece di attraversare le page tables per ogni processo, il memory manager, per ogni pagina di memoria fisica, crea una lista concatenata (o linked list) di puntatori ai record delle page-table (page-table entries o PTE) di ciascun processo che attualmente ha un riferimento a quella pagina. Questa lista concatenata di puntatori viene chiamata PTE chain. La PTE chain rende molto più veloce l'identificazione dei processi che stanno usando una pagina di memoria. Tutto ha un prezzo, naturalmente. Quello che guadagniamo in performance usando il reverse mappings ha un costo. Il costo principale è un possibile memory overhead. Per tenere traccia di tutti i reverse mapping, c'è bisogno di una certa quantità di memoria. Ciascun record nella PTE chain usa 4 byte per ogni puntatore al record di una page-table, più altri 4 byte per il puntatore al successivo record della PTE chain. Non dobbiamo dimenticare che una lista concatenata consiste di una sequenza di nodi, ognuno contenente campi di dati arbitrari ed uno o due riferimenti ("link") che puntano al nodo successivo e/o precedente, in modo da non permettere l'accesso casuale, bensì solo quello sequenziale. Nella PTE chain, a volte è possibile inserire un solo record, invece di creare una linked list, ma solo se esiste un solo riferimento alla pagina, vale a dire solo se quella pagina è usata da un solo processo. Questo metodo è chiamato page-direct approach. Se la pagina verrà poi mappata da un altro processo, sarà necessario tornare alla PTE chain. Fino al momento in cui quell'ottimizzazione sarà attiva, verrà attivata una flag, al fine di renderlo noto al memory manager. Normalmente, il memory manager gestisce pagine di memoria di 4KB, almeno sui sistemi x86, anche se le dimensioni delle pagine dipendono dall'architettura del sistema. Per la gran parte degli usi, i 4KB sono il modo più efficiente per gestire la memoria. Alcune applicazioni, tuttavia, fanno uso di una gran quantità di memoria, come nel caso dei grandi database. Per ogni pagina mappata da ciascun processo, un record viene creato nella page-table per tradurre l'indirizzo virtuale in un indirizzo fisico. Nel caso di un processo che mappa 1 GB di memoria, suddiviso in pagine da 4KB, diventano necessari 262,144 record nella page-table: 1.073.741.824 ÷ 4.096 = 262.144 Se, come abbiamo visto prima, ciascun record della page-table consuma 8 byte, ecco che avremo bisogno di 2MB di memoria aggiuntiva, per ogni 1GB di memoria mappata. Il problema, poi, aumenta se abbiamo più processi che condividono quella memoria. In questo caso, ogni processo che mappa lo stesso 1GB di memoria avrebbe bisogno dei suoi 2MB di record della page-table. Con un numero sufficiente di processi, la quantità di memoria aggiuntiva necessaria potrebbe superare la quantità di memoria richiesta dall'applicazione. Una soluzione potrebbe essere quella di usare pagine di dimensioni superiori. I moderni processori supportano due dimensioni per le pagine (piccola e grande), mentre alcuni ne supportano anche di più. Sui sistemi x86, una pagina può arrivare ad una dimensione di 4MB. Con una pagina di 4MB, lo stesso 1GB di memoria può essere mappata con soli 256 record nella page-table, invece dei 262.144. Questo comporterebbe un fabbisogno aggiuntivo (overhead) di soli 2,048 byte, invece dei 2MB. Le Page-tables possono essere memorizzate nella memoria bassa, nelle macchine a 32-bit. Ma, la memoria bassa occupa solo i primi 896 MB della memoria fisica (con i primi 10MB dedicati alla memoria DMA) e, in più, è richiesta dal kernel per le sue operazioni. In situazioni in cui le applicazioni usano un gran numero di processi, mappando molte aree di memoria, la memoria bassa può in breve tempo scarseggiare. Nel kernel 2.6, un'opzione di configurazione, Highmem PTE, permette di memorizzare i record delle page-table nella high memory (memoria alta), liberando così la memoria bassa e lasciandola al kernel.
|
|||||||||
Virtual Memory Subsystem in Linux Kernel 2.6 | Disclaimer: questo è un link a contenuti ospitati su server esterni. |