diff options
author | Gabor Kovesdan <gabor@FreeBSD.org> | 2012-10-01 09:53:01 +0000 |
---|---|---|
committer | Gabor Kovesdan <gabor@FreeBSD.org> | 2012-10-01 09:53:01 +0000 |
commit | b4346b9b2dfe86a97907573086dff096850dcb1d (patch) | |
tree | 9b951977cbd22dada9b868ac83b1d56791ea3859 /it_IT.ISO8859-15/articles/vm-design/article.sgml | |
parent | bee5d224febbeba11356aa848006a4f5f9e24b30 (diff) | |
download | doc-b4346b9b2dfe86a97907573086dff096850dcb1d.tar.gz doc-b4346b9b2dfe86a97907573086dff096850dcb1d.zip |
- Rename .sgml files to .xml
- Reflect the rename in referencing files
Approved by: doceng (implicit)
Notes
Notes:
svn path=/head/; revision=39631
Diffstat (limited to 'it_IT.ISO8859-15/articles/vm-design/article.sgml')
-rw-r--r-- | it_IT.ISO8859-15/articles/vm-design/article.sgml | 1048 |
1 files changed, 0 insertions, 1048 deletions
diff --git a/it_IT.ISO8859-15/articles/vm-design/article.sgml b/it_IT.ISO8859-15/articles/vm-design/article.sgml deleted file mode 100644 index 30a317b88b..0000000000 --- a/it_IT.ISO8859-15/articles/vm-design/article.sgml +++ /dev/null @@ -1,1048 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-15" standalone="no"?> -<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V4.2-Based Extension//EN" - "../../../share/sgml/freebsd42.dtd" [ -<!ENTITY % entities PUBLIC "-//FreeBSD//ENTITIES DocBook FreeBSD Entity Set//IT" "../../share/sgml/entities.ent"> -%entities; -]> - -<!-- - The FreeBSD Italian Documentation Project - - $FreeBSD$ - Original revision: 1.16 ---> - -<article lang="it"> - <articleinfo> - <title>Elementi di progettazione del sistema di VM di FreeBSD</title> - - <authorgroup> - <author> - <firstname>Matthew</firstname> - - <surname>Dillon</surname> - - <affiliation> - <address> - <email>dillon@apollo.backplane.com</email> - </address> - </affiliation> - </author> - </authorgroup> - - <legalnotice id="trademarks" role="trademarks"> - &tm-attrib.freebsd; - &tm-attrib.linux; - &tm-attrib.microsoft; - &tm-attrib.opengroup; - &tm-attrib.general; - </legalnotice> - - <pubdate>$FreeBSD$</pubdate> - - <releaseinfo>$FreeBSD$</releaseinfo> - - <abstract> - <para>Il titolo è in realtà solo un modo complicato per dire - che cercherò di descrivere l'intera enchilada della memoria - virtuale (VM), sperando di farlo in una maniera che chiunque possa - seguire. - Nell'ultimo anno mi sono concentrato su un certo numero di sottosistemi - principali del kernel in FreeBSD, trovando quelli della VM (la memoria - virtuale) e dello Swap i più interessanti, e considerando quello - di NFS <quote>un lavoretto necessario</quote>. - Ho riscritto solo piccole porzioni di quel codice. Nell'arena - della VM la sola grossa riscrittura che ho affrontato è stata - quella del sottosistema di swap. - La maggior parte del mio lavoro è stato di pulizia e - mantenimento, con solo alcune moderate riscritture di codice e - nessuna correzione rilevante a livello algoritmico nel sottosistema - della VM. Il nocciolo della base teorica del sottosistema - rimane immutato ed un bel po' del merito per gli sforzi di - modernizzazione negli ultimi anni appartiene a John Dyson e David - Greenman. Poiché non sono uno storico come Kirk non - tenterò di marcare tutte le varie caratteristiche con i nomi - delle relative persone, perché sbaglierei - invariabilmente.</para> - - &trans.it.surrender; - </abstract> - - <legalnotice> - <para>Questo articolo è stato pubblicato in origine nel numero di - gennaio 2000 di <ulink - url="http://www.daemonnews.org/">DaemonNews</ulink>. - Questa versione dell'articolo può includere aggiornamenti da - parte di Matt e di altri autori per riflettere i cambiamenti - nell'implementazione della VM di FreeBSD.</para> - </legalnotice> - </articleinfo> - - <sect1 id="introduction"> - <title>Introduzione</title> - - <para>Prima di andare avanti con la descrizione del progetto effettivo - della VM spendiamo un po' di tempo sulla necessità di mantenere - e modernizzare una qualunque base di codice longeva. - Nel mondo della programmazione, gli algoritmi tendono ad essere più - importanti del codice ed è dovuto alle radici accademiche - di BSD che si è prestata grande attenzione alla progettazione - algoritmica sin dal principio. - Una maggiore attenzione al design in genere conduce ad una base di codice - flessibile e pulita che può essere modificata abbastanza - semplicemente, estesa, o rimpiazzata nel tempo. - Mentre BSD viene considerato un sistema operativo <quote>vecchio</quote> - da alcune persone, quelli di noi che lavorano su di esso tendono - a considerarlo come una base di codice <quote>matura</quote> - che ha vari componenti modificati, estesi, o rimpiazzati con codice - moderno. Questa si è evoluta, e FreeBSD è all'avanguardia, - non importa quanto possa essere vecchio qualche pezzo di codice. - Questa è una distinzione importante da fare ed una di quelle che - sfortunatamente sfuggono alla maggior parte delle persone. Il più - grande errore che un programmatore possa fare è non imparare - dalla storia, e questo è precisamente l'errore che molti sistemi - operativi moderni hanno commesso. &windowsnt; è il miglior esempio - di questo, e le conseguenze sono state disastrose. Anche Linux commette - questo errore a un certo livello—abbastanza perché noi - appassionati di BSD possiamo scherzarci su ogni tanto, comunque. - Il problema di Linux è semplicemente la mancanza di esperienza e - di una storia con la quale confrontare le idee, un problema che sta - venendo affrontato rapidamente dalla comunità Linux nello stesso - modo in cui è stato affrontato da quella BSD—con il continuo - sviluppo di codice. La gente di &windowsnt;, d'altro canto, fa - ripetutamente gli stessi errori risolti da &unix; decadi fa e poi impiega - anni nel risolverli. E poi li rifanno, ancora, e ancora. - Soffrono di un preoccupante caso di <quote>non è stato progettato - qui</quote> e di <quote>abbiamo sempre ragione perché il nostro - dipartimento marketing dice così</quote>. Io ho pochissima - tolleranza per chiunque non impari dalla storia.</para> - - <para>La maggior parte dell'apparente complessità di progettazione di - FreeBSD, specialmente nel sottosistema VM/Swap, è una conseguenza - diretta dell'aver dovuto risolvere importanti problemi di prestazioni - legati a varie condizioni. Questi problemi non sono dovuti a cattivi - progetti algoritmici ma sorgono invece da fattori ambientali. - In ogni paragone diretto tra piattaforme, questi problemi - diventano più evidenti quando le risorse di sistema cominciano ad - essere stressate. - Mentre descrivo il sottosistema VM/Swap di FreeBSD il lettore - dovrebbe sempre tenere a mente almeno due punti. Primo, l'aspetto - più importante nel design prestazionale è ciò che - è noto come <quote>Ottimizzazione del Percorso Critico</quote>. - Accade spesso che le ottimizzazioni prestazionali aggiungano - un po di impurità al codice per far migliorare il percorso critico. - Secondo, un progetto solido e generalizzato, funziona meglio di - un progetto pesantemente ottimizzato, alla lunga. Mentre un progetto - generale può alla fin fine essere più lento di un sistema - pesantemente ottimizzato quando vengono implementati inizialmente, il - progetto generalizzato tende ad essere più semplice da adattare - alle condizioni variabili mentre quello pesantemente ottimizzato finisce - per dover essere gettato via. Ogni base di codice che dovrà - sopravvivere ed essere mantenibile per anni deve dunque essere progettata - con attenzione fin dall'inizio anche se questo può portare a - piccoli peggioramenti nelle prestazioni. - Vent'anni fa c'era ancora gente che sosteneva che programmare in assembly - era meglio che programmare in linguaggi di alto livello, perché - si poteva produrre codice che era dieci volte più veloce. Oggi, - la fallacia di tale argomento è ovvia—così come i - paralleli con il design algoritmico e la generalizzazione del - codice.</para> - </sect1> - - <sect1 id="vm-objects"> - <title>Oggetti VM</title> - - <para>Il modo migliore per iniziare a descrivere il sistema di VM di FreeBSD - è guardandolo dalla prospettiva di un processo a livello - utente. Ogni processo utente vede uno spazio di indirizzamento della VM - singolo, privato e contiguo, contenente molti tipi di oggetti di memoria. - Questi oggetti hanno varie caratteristiche. - Il codice del programma e i dati del programma sono effettivamente - un singolo file mappato in memoria (il file binario che è stato - eseguito), ma il codice di programma è di sola lettura mentre i - dati del programma sono copy-on-write <footnote> - <para>I dati copy on write sono dati che vengono copiati solo al momento - della loro effettiva modifica</para> - </footnote>. Il BSS del programma è solamente una zona di memoria - allocata e riempita con degli zero su richiesta, detta in inglese - <quote>demand zero page fill</quote>. - Nello spazio di indirizzamento possono essere mappati anche file - arbitrari, che è in effetti il meccanismo con il quale funzionano - le librerie condivise. Tali mappature possono richiedere modifiche per - rimanere private rispetto al processo che le ha effettuate. - La chiamata di sistema fork aggiunge una dimensione completamente nuova - al problema della gestione della VM in cima alla complessità - già data.</para> - - <para>Una pagina di dati di un programma (che è una basilare pagina - copy-on-write) illustra questa complessità. Un programma binario - contiene una sezione di dati preinizializzati che viene inizialmente - mappata direttamente in memoria dal file del programma. - Quando un programma viene caricato nello spazio di memoria virtuale di un - processo, questa area viene inizialmente copiata e mappata in memoria dal - binario del programma stesso, permettendo al sistema della VM di - liberare/riusare la pagina in seguito e poi ricaricarla dal binario. - Nel momento in cui un processo modifica questi dati, comunque, il - sistema della VM deve mantenere una copia privata della pagina per quel - processo. Poiché la copia privata è stata modificata, il - sistema della VM non può più liberarlo, poiché non ci - sarebbe più nessuna possibilità di recuperarlo in - seguito.</para> - - <para>Noterai immediatamente che quella che in origine era soltanto - una semplice mappatura di un file è diventata qualcosa di - più complesso. - I dati possono essere modificati pagina per pagina - mentre una mappatura di file coinvolge molte pagine alla volta. - La complessità aumenta ancora quando un processo esegue una fork. - Quando un processo esegue una fork, il risultato sono due - processi—ognuno con il proprio spazio di indirizzamento privato, - inclusa ogni modifica fatta dal processo originale prima della chiamata a - <function>fork()</function>. Sarebbe stupido per un sistema di VM creare - una copia completa dei dati al momento della <function>fork()</function> - perché è abbastanza probabile che almeno uno dei due - processi avrà bisogno soltanto di leggere da una certa pagina da - quel momento in poi, permettendo di continuare ad usare la - pagina originale. Quella che era una pagina privata viene di nuovo - resa una copy-on-write, poiché ogni processo (padre e figlio) si - aspetta che i propri cambiamenti rimangano privati per loro e non abbiano - effetti sugli altri.</para> - - <para>FreeBSD gestisce tutto ciò con un modello a strati di oggetti - VM. Il file binario originale del programma risulta come lo strato di - Oggetti VM più basso. - Un livello copy-on-write viene messo sopra questo per mantenere quelle - pagine che sono state copiate dal file originale. - Se il programma modifica una pagina di dati appartenente al file originale - il sistema dell VM prende un page fault <footnote> - <para>Un page fault, o <quote>mancanza di pagina</quote>, - corrisponde ad una mancanza di una determinata pagina di memoria a un - certo livello, ed alla necessità di copiarla da un livello - più lento. Ad esempio se una pagina di memoria è stata - spostata dalla memoria fisica allo spazio di swap su disco, e viene - richiamata, si genera un page fault e la pagina viene di nuovo copiata - in ram.</para> - </footnote> e fa una copia della pagina nel livello più alto. - Quando un processo effettua una fork, vengono aggiunti altri livelli di - Oggetti VM. Tutto questo potrebbe avere un po' più senso con un - semplice esempio. - Una <function>fork()</function> è un'operazione comune per ogni - sistema *BSD, dunque questo esempio prenderà in considerazione un - programma che viene avviato ed esegue una fork. Quando il processo viene - avviato, il sistema della VM crea uno starto di oggetti, chiamiamolo - A:</para> - - <mediaobject> - <imageobject> - <imagedata fileref="fig1" format="EPS"/> - </imageobject> - - <textobject> - <literallayout class="monospaced">+---------------+ -| A | -+---------------+</literallayout> - </textobject> - - <textobject> - <phrase>Un'immagine</phrase> - </textobject> - </mediaobject> - - <para>A rappresenta il file—le pagine possono essere - spostate dentro e fuori dal mezzo fisico del file se necessario. - Copiare il file dal disco è sensato per un programma, - ma di certo non vogliamo effettuare il page out <footnote> - <para>La copia dalla memoria al disco, l'opposto del page in, la - mappatura in memoria.</para> - </footnote> e sovrascrivere l'eseguibile. - Il sistema della VM crea dunque un secondo livello, B, che verrà - copiato fisicamente dallo spazio di swap:</para> - - <mediaobject> - <imageobject> - <imagedata fileref="fig2" format="EPS"/> - </imageobject> - - <textobject> - <literallayout class="monospaced">+---------------+ -| B | -+---------------+ -| A | -+---------------+</literallayout> - </textobject> - </mediaobject> - - <para>Dopo questo, nella prima scrittura verso una pagina, viene creata una - nuova pagina in B, ed il suo contenuto viene inizializzato con i dati di - A. Tutte le pagine in B possono essere spostate da e verso un dispositivo - di swap. Quando il programma esegue la fork, il sistema della VM crea - due nuovi livelli di oggetti—C1 per il padre e C2 per il - figlio—che restano sopra a B:</para> - - <mediaobject> - <imageobject> - <imagedata fileref="fig3" format="EPS"/> - </imageobject> - - <textobject> - <literallayout class="monospaced">+-------+-------+ -| C1 | C2 | -+-------+-------+ -| B | -+---------------+ -| A | -+---------------+</literallayout> - </textobject> - </mediaobject> - - <para>In questo caso, supponiamo che una pagina in B venga modificata dal - processo genitore. Il processo subirà un fault di copy-on-write e - duplicherà la pagina in C1, lasciando la pagina originale in B - intatta. - Ora, supponiamo che la stessa pagina in B venga modificata dal processo - figlio. Il processo subirà un fault di copy-on-write e - duplicherà la pagina in C2. - La pagina originale in B è ora completamente nascosta poiché - sia C1 che C2 hanno una copia e B potrebbe teoricamente essere distrutta - (se non rappresenta un <quote>vero</quote> file); - comunque, questo tipo di ottimizzazione non è triviale da - realizzare perché è di grana molto fine. - FreeBSD non effettua questa ottimizzazione. - Ora, supponiamo (come è spesso il caso) che - il processo figlio effettui una <function>exec()</function>. Il suo - attuale spazio di indirizzamento è in genere rimpiazzato da un - nuovo spazio di indirizzamento rappresentante il nuovo file. - In questo caso il livello C2 viene distrutto:</para> - - <mediaobject> - <imageobject> - <imagedata fileref="fig4" format="EPS"/> - </imageobject> - - <textobject> - <literallayout class="monospaced">+-------+ -| C1 | -+-------+-------+ -| B | -+---------------+ -| A | -+---------------+</literallayout> - </textobject> - </mediaobject> - - <para>In questo caso, il numero di figli di B scende a uno, e tutti gli - accessi a B avvengono attraverso C1. Ciò significa che B e C1 - possono collassare insieme in un singolo strato. - Ogni pagina in B che esista anche in C1 viene cancellata da - B durante il crollo. Dunque, anche se l'ottimizzazione nel passo - precedente non era stata effettuata, possiamo recuperare le pagine morte - quando il processo esce o esegue una <function>exec()</function>.</para> - - <para>Questo modello crea un bel po' di problemi potenziali. Il primo - è che ci si potrebbe ritrovare con una pila abbastanza profonda di - Oggetti VM incolonnati che costerebbe memoria e tempo per la ricerca - quando accadesse un fault. Può verificarsi un ingrandimento della - pila quando un processo esegue una fork dopo l'altra (che sia il padre o - il figlio). Il secondo problema è che potremmo ritrovarci con - pagine morte, inaccessibili nella profondità della pila degli - Oggetti VM. Nel nostro ultimo esempio se sia il padre che il figlio - modificano la stessa pagina, entrambi hanno una loro copia della pagina e - la pagina originale in B non è più accessibile - da nessuno. Quella pagina in B può essere liberata.</para> - - <para>FreeBSD risolve il problema della profondità dei livelli con - un'ottimizzazione speciale detta <quote>All Shadowed Case</quote> (caso - dell'oscuramento totale). - Questo caso accade se C1 o C2 subiscono sufficienti COW fault (COW - è l'acronimo che sta per copy on write) da oscurare completamente - tutte le pagine in B. - Ponimo che C1 abbia raggiunto questo livello. C1 può ora - scavalcare B del tutto, dunque invece di avere C1->B->A e C2->B->A adesso - abbiamo C1->A e C2->B->A. - ma si noti cos'altro è accaduto—ora B ha solo un riferimento - (C2), dunque possiamo far collassare B e C2 insieme. - Il risultato finale è che B viene cancellato - interamente e abbiamo C1->A e C2->A. Spesso accade che B contenga un - grosso numero di pagine e ne' C1 ne' C2 riescano a oscurarlo - completamente. Se eseguiamo una nuova fork e creiamo un insieme di - livelli D, comunque, è molto più probabile che uno dei - livelli D sia eventualmente in grado di oscurare completamente l'insieme - di dati più piccolo rappresentato da C1 o C2. La stessa - ottimizzazione funzionerà in ogni punto nel grafico ed il - risultato di ciò è che anche su una macchina con - moltissime fork le pile degli Oggetti VM tendono a non superare una - profondità di 4. Ciò è vero sia per il padre che per - il figlio ed è vero nel caso sia il padre a eseguire la fork ma - anche se è il figlio a eseguire fork in cascata.</para> - - <para>Il problema della pagina morta esiste ancora nel caso C1 o C2 non - oscurino completamente B. A causa delle altre ottimizzazioni questa - eventualità - non rappresenta un grosso problema e quindi permettiamo semplicemente - alle pagine di essere morte. Se il sistema si trovasse con poca memoria - le manderebbe in swap, consumando un po' di swap, ma così - è.</para> - - <para>Il vantaggio del modello ad Oggetti VM è che - <function>fork()</function> è estremamente veloce, poiché - non deve aver luogo nessuna copia di dati effettiva. Lo svantaggio - è che è possibile costruire un meccanismo a livelli di - Oggetti VM relativamente complesso che rallenterebbe la gestione dei page - fault, e consumerebbe memoria gestendo le strutture degli Oggetti VM. - Le ottimizazioni realizzate da FreeBSD danno prova di ridurre - i problemi abbastanza da poter essere ignorati, non lasciando - nessuno svantaggio reale.</para> - </sect1> - - <sect1 id="swap-layers"> - <title>Livelli di SWAP</title> - - <para>Le pagine di dati private sono inizialmente o pagine - copy-on-write o pagine zero-fill. - Quando avviene un cambiamento, e dunque una copia, l'oggetto di copia - originale (in genere un file) non può più essere utilizzato - per salvare la copia quando il sistema della VM ha bisogno di - riutilizzarla per altri scopi. A questo punto entra in gioco lo SWAP. Lo - SWAP viene allocato per creare spazio dove salvare memoria che altrimenti - non sarebbe disponibile. FreeBSD alloca la struttura di gestione di - un Oggetto VM solo quando è veramente necessario. - Ad ogni modo, la struttura di gestione dello swap ha avuto storicamente - dei problemi.</para> - - <para>Su FreeBSD 3.X la gestione della struttura di swap prealloca un - array che contiene l'intero oggetto che necessita di subire - swap—anche se solo poche pagine di quell'oggetto sono effettivamente - swappate questo crea una frammentazione della memoria del kernel quando - vengono mappati oggetti grandi, o processi con grandi dimensioni - all'esecuzione (large runsizes, RSS). Inoltre, per poter tenere traccia - dello spazio di swap, viene mantenuta una <quote>lista dei buchi</quote> - nella memoria del kernel, ed anche questa tende ad essere pesantemente - frammentata. Poiché la <quote>lista dei buchi</quote> è una - lista lineare, l'allocazione di swap e la liberazione hanno prestazioni - non ottimali O(n) per ogni pagina. - Questo richiede anche che avvengano allocazioni di memoria - durante il processo di liberazione dello swap, e questo crea - problemi di deadlock, blocchi senza uscita, dovuti a scarsa memoria. - Il problema è ancor più esacerbato dai buchi creati a causa - dell'algoritmo di interleaving. - Inoltre il blocco di swap può divenire frammentato molto facilmente - causando un'allocazione non contigua. Anche la memoria del Kernel deve - essere allocata al volo per le strutture aggiuntive di gestione dello - swap quando avviene uno swapout. È evidente che c'era molto spazio - per dei miglioramenti.</para> - - <para>Per FreeBSD 4.X, ho completamente riscritto il sottosistema di swap. - Con questa riscrittura, le strutture di gestione dello swap vengono - allocate attraverso una tabella di hash invece che con un array lineare - fornendo una dimensione di allocazione fissata e una granularità - molto maggiore. - Invece di usare una lista lineare collegata per tenere traccia delle - riserve di spazio di swap, essa usa una mappa di bit di blocchi di swap - organizzata in una struttura ad albero radicato con riferimenti allo - spazio libero nelle strutture nei nodi dell'albero. Ciò rende in - effetti l'operazione di allocazione e liberazione delle risorse - un'operazione O(1). - L'intera mappa di bit dell'albero radicato viene anche preallocata in modo - da evitare l'allocazione di memoria kernel durante le operazioni di swap - critiche nei momenti in cui la memoria disponibile è ridotta. - Dopo tutto, il sistema tende a fare uso dello swap quando ha poca memoria - quindi dovremmo evitare di allocare memoria per il kernel in quei momenti - per poter evitare potenziali deadlock. Infine, per ridurre la - frammentazione l'albero radicato è in grado di allocare grandi - spezzoni contigui in una volta, saltando i pezzetti frammentati. - Non ho ancora compiuto il passo finale di avere un <quote>puntatore di - supportoall'allocazione</quote> che scorra su una porzione di swap nel - momento in cui vengano effettuate delle allocazioni, in modo da garantire - ancor di più le allocazioni contigue o almeno una località - nel riferimento, ma ho assicurato che un'aggiunta simile possa essere - effettuata.</para> - </sect1> - - <sect1 id="freeing-pages"> - <title>Quando liberare una pagina</title> - - <para>Poiché il sistema della VM usa tutta la memoria disponibile - per il caching del disco, in genere ci sono pochissime pagine veramente - libere. Il sistema della VM dipende dalla possibilità di - scegliere in maniera appropriata le pagine che non sono in uso per - riusarle in nuove allocazioni. Selezionare le pagine ottimali da liberare - è forse la funzione singola più importante che possa essere - eseguita da una VM perché se si effettua una selezione non - accurata, il sistema della VM può essere forzato a recuperare - pagine dal disco in modo non necessari, degradando seriamente le - prestazioni del sistema.</para> - - <para>Quanto sovraccarico siamo disposti a sopportare nel percorso critico - per evitare di liberare la pagina sbagliata? Ogni scelta sbagliata che - facciamo ci costerà centinaia di migliaia di cicli di CPU ed uno - stallo percettibile nei processi coinvolti, dunque permettiamo un - sovraccarico significativo in modo da poter avere la certezza che la - pagina scelta sia quella giusta. - Questo è il motivo per cui FreeBSD tende ad avere prestazioni - migliori di altri sistemi quando le risorse di memoria vengono - stressate.</para> - - <para>L'algoritmo di determinazione della pagina da liberare - è costruito su una storia di uso delle pagine di memoria. - Per acquisire tale storia, il sistema si avvantaggia di una - caratteristica della maggior parte dell'hardware moderno, il bit che - indica l'attività di una pagina (page-used bit).</para> - - <para>In qualsiasi caso, il page-used bit viene azzerato e in un momento - seguente il sistema della VM passa di nuovo sulla pagina e vede che il - page-used bit è stato di nuovo attivato. Questo indica che la - pagina viene ancora usata attivamente. - Il bit ancora disattivato è un indice che quella pagina non viene - usata attivamente. - Controllando questo bit periodicamente, viene sviluppata una storia - d'uso (in forma di contatore) per la pagina fisica. Quando il sistema - della VM avrà bisogno di liberare delle pagine, controllare questa - storia diventa la pietra angolare nella determinazione del candidato - migliore come pagina da riutilizzare.</para> - - <sidebar> - <title>E se l'hardware non ha un page-used bit?</title> - - <para>Per quelle piattaforme che non hanno questa caratteristica, il - sistema in effetti emula un page-used bit. Esso elimina la mappatura di - una pagina, o la protegge, forzando un page fault se c'è un - accesso successivo alla pagina. - Quando avviene il page fault, il sistema segnala semplicemente - la pagina come usata e la sprotegge in maniera che possa essere usata. - Mentre prendere tale page fault solo per determinare se una pagina - è in uso può apparire una scelta costosa, in realtà - essa lo è molto meno che riusare la pagina per altri scopi, per - dover poi scoprire che un processo ne aveva ancora bisogno e dovere - andare a cercarla di nuovo su disco.</para> - </sidebar> - - <para>FreeBSD fa uso di parecchie code per le pagine per raffinare - ulteriormente la selezione delle pagine da riutilizzare, come anche per - determinare quando le pagine sporche devono essere spostate dalla memoria - e immagazzinate da qualche parte. Poiché le tabelle delle pagine - sono entità dinamiche in FreeBSD, non costa praticamente nulla - eliminare la mappatura di una pagina dallo spazio di indirizzamento di un - qualsiasi processo che la stia usando. Quando una pagina candidata - è stata scelta sulla base del contatore d'uso, questo è - esattamente quello che viene fatto. - Il sistema deve effettuare una distinzione tra pagine pulite che - possono essere teoricamente liberate in qualsiasi momento, e pagine - sporche che devono prima essere scritte (salvate) per poter essere - riutilizzabili. - Quando una pagina candidata viene trovata viene spostata nella coda - delle pagine inattive, se è una pagina sporca, o nella coda di - cache se è pulita. - Un algoritmo separato basato su un rapporto sporche/pulite - determina quando le pagine sporche nella coda inattiva devono essere - scritte su disco. Una volta che è stato fatto questo, le pagine - ormai salvate vengono spostate dalla coda delle inattive alla coda di - cache. A questo punto, le pagine nella coda di cache possono ancora - essere riattivate da un VM fault ad un costo relativamente basso. - Ad ogni modo, le pagine nella coda di cache vengono considerate - <quote>immediatamente liberabili</quote> e verranno riutilizzate con un - metodo LRU (least-recently used <footnote> - <para>Usate meno recentemente. Le pagine che non vengono usate da molto - tempo probabilmente non saranno necessarie a breve, e possono essere - liberate.</para> - </footnote>) quando il sistema avrà bisogno di allocare nuova - memoria.</para> - - <para>È importante notare che il sistema della VM di FreeBSD tenta - di separare pagine pulite e sporche per l'espressa ragione di evitare - scritture non necessarie di pagine sporche (che divorano banda di I/O), e - non sposta le pagine tra le varie code gratuitamente quando il - sottosistema non viene stressato. Questo è il motivo per cui - dando un <command>systat -vm</command> vedrai sistemi con contatori della - coda di cache bassi e contatori della coda delle pagine attive molto alti. - Quando il sistema della VM diviene maggiormente stressato, esso fa un - grande sforzo per mantenere le varie code delle pagine ai livelli - determinati come più efficenti. - Per anni è circolata la leggenda urbana che Linux facesse un lavoro - migliore di FreeBSD nell'evitare gli swapout, ma in pratica questo non - è vero. Quello che stava effettivamente accadendo era che FreeBSD - stava salvando le pagine inutilizzate proattivamente per fare spazio - mentre Linux stava mantendendo le pagine inutilizzate lasciando meno - memoria disponibile per la cache e le pagine dei processi. - Non so se questo sia vero ancora oggi.</para> - </sect1> - - <sect1 id="prefault-optimizations"> - <title>Pre-Faulting e Ottimizzazioni di Azzeramento</title> - - <para>Subire un VM fault non è costoso se la pagina sottostante - è già nella memoria fisica e deve solo essere mappata di - nuovo nel processo, ma può divenire costoso nel caso se ne - subiscano un bel po' su base regolare. Un buon esempio di ciò si - ha eseguendo un programma come &man.ls.1; o &man.ps.1; ripetutamente. - Se il binario del programma è mappato in memoria ma non nella - tabella delle pagine, allora tutte le pagine che verranno accedute dal - programmma dovranno generare un page fault ogni volta che il programma - viene eseguito. - Ciò non è necessario quando le pagine in questione sono - già nella cache della VM, quindi FreeBSD tenterà di - pre-popolare le tabelle delle pagine di un processo con quelle pagine che - sono già nella VM Cache. Una cosa che FreeBSD non fa ancora - è effettuare il pre-copy-on-write di alcune pagine nel caso di una - chiamata a exec. - Ad esempio, se esegui il programma &man.ls.1; mentre stai eseguendo - <command>vmstat 1</command> noterai che subisce sempre un certo numero - di page fault, anche eseguendolo ancora e ancora. Questi sono - zero-fill fault, legati alla necessità di azzerare memoria, - non program code fault, legati alla copia dell'eseguibile in memoria - (che erano già stati gestiti come pre-fault). - Pre-copiare le pagine all'exec o alla fork è un'area che potrebbe - essere soggetta a maggior studio.</para> - - <para>Una larga percentuale dei page fault che accadono è composta di - zero-fill fault. In genere è possibile notare questo fatto - osservando l'output di <command>vmstat -s</command>. - Questi accadono quando un processo accede a pagine nell'area del BSS. - Ci si aspetta che l'area del BSS sia composta inizialmente da zeri - ma il sistema della VM non si preoccupa di allocare nessuna memoria - finché il processo non ne ha effettivamente bisogno. - Quindi nel momento in cui accade un fault il sistema della VM non - deve solo allocare una nuova pagina, ma deve anche azzerarla. - Per ottimizzare l'operazione di azzeramento, il sistema della VM - ha la capacità di pre-azzerare le pagine e segnalarle come tali, - e di richiedere pagine pre-azzerate quando avvengono zero-fill fault. - Il pre-azzeramento avviene quando la CPU è inutilizzata ma il - numero di pagine che vengono pre-azzerate dal sistema è limitato - per evitare di spazzare via la cache della memoria. Questo è un - eccellente esempio di complessità aggiunta al sistema della VM per - ottimizare il percorso critico.</para> - </sect1> - - <sect1 id="page-table-optimizations"> - <title>Ottimizzazioni della Tabella delle Pagine </title> - - <para>Le ottimizzazioni alla tabella delle pagine costituiscono - La parte più controversa nel design della VM di FreeBSD ed ha - mostrato un po' di affanno con l'avvento di un uso pesante di - <function>mmap()</function>. - Penso che questa sia una caratteristiche della maggior parte dei - BSD anche se non sono sicuro di quando è stata introdotta - la prima volta. Ci sono due ottimizzazioni maggiori. La prima è - che le tabelle della pagine hardware non contengono uno stato persistente - ma possono essere gettate via in qualsiasi momento con un sovraccarico di - gestione minimo. - La seconda è che ogni pagina attiva nel sistema ha una struttura di - controllo <literal>pv_entry</literal> che è integrata con la - struttura <literal>vm_page</literal>. FreeBSD può semplicemente - operare attraverso quelle mappature di cui è certa l'esistenza, - mentre Linux deve controllare tutte le tabelle delle pagine che - <emphasis>potrebbero</emphasis> contenere una mappatura specifica per - vedere se lo stanno effettivamente facendo, il che può portare ad - un sovraccarico computazionale O(n^2) in alcune situazioni. - È per questo che FreeBSD tende a fare scelte migliori su quale - pagina riutilizzare o mandare in swap quando la memoria è messa - sotto sforzo, fornendo una miglior performance sotto carico. Comunque, - FreeBSD richiede una messa a punto del kernel per accomodare situazioni - che richiedano grandi spazi di indirizzamento condivisi, come quelli che - possono essere necessari in un sistema di news perché potrebbe - esaurire il numero di struct <literal>pv_entry</literal>.</para> - - <para>Sia Linux che FreeBSD necessitano di lavoro in quest'area. - FreeBSD sta cercando di massimizzare il vantaggio di avere un modello di - mappatura attiva potenzialmente poco denso (non tutti i processi hanno - bisogno di mappare tutte le pagine di una libreria condivisa, ad esempio), - mentre linux sta cercando di semplificare i suoi algoritmi. FreeBSD - generalmente ha dei vantaggi prestazionali al costo di un piccolo spreco - di memoria in più, ma FreeBSD crolla nel caso in cui un grosso file - sia condiviso massivamente da centinaia di processi. - Linux, d'altro canto, crolla nel caso in cui molti processi mappino a - macchia di leopardo la stessa libreria condivisa e gira in maniera non - ottimale anche quando cerca di determinare se una pagina deve essere - riutilizzata o no.</para> - </sect1> - - <sect1 id="page-coloring-optimizations"> - <title>Colorazione delle Pagine</title> - - <para>Concluderemo con le ottimizzazioni di colorazione delle pagine. - La colorazione delle pagine è un'ottimizzazione prestazionale - progettata per assicurare che gli accessi a pagine contigue nella memoria - virtuale facciano il miglior uso della cache del processore. Nei - tempi antichi (cioè più di 10 anni fa) le cache dei - processori tendevano a mapparela memoria virtuale invece della memoria - fisica. Questo conduceva ad un numero enorme di problemi inclusa la - necessità di ripulire la cache ad ogni cambio di contesto, in - alcuni casi, e problemi con l'aliasing dei dati nella cache. - Le cache dei processori moderni mappano la memoria fisica proprio per - risolvere questi problemi. - Questo significa che due pagine vicine nello spazio di indirizzamento - dei processi possono non corrispondere a due pagine vicine nella cache. - In effetti, se non si è attenti pagine affiancate nella memoria - virtuale possono finire con l'occupare la stessa pagina nella cache del - processore—portando all'eliminazione prematura di dati - immagazzinabili in cache e riducendo le prestazioni della cache. - Ciò è vero anche con cache set-associative <footnote> - <para>set-associative sta per associative all'interno di un insieme, in - quanto c'è un insieme di blocchi della cache nei quale puo - essere mappato un elemento della memoria fisica.</para> - </footnote> a molte vie (anche se l'effetto viene in qualche maniera - mitigato).</para> - - <para>Il codice di allocazione della memoria di FreeBSD implementa - le ottimizizzazioni di colorazione delle pagine, ciò significa che - il codice di allocazione della memoria cercherà di trovare delle - pagine libere che siano vicine dal punto di vista della cache. - Ad esempio, se la pagina 16 della memoria fisica è assegnata - alla pagina 0 della memoria virtuale di un processo e la cache può - contenere 4 pagine, il codice di colorazione delle pagine non - assegnerà la pagina 20 di memoria fisica alla pagina 1 di - quella virtuale. - Invece, gli assegnerà la pagina 21 della memoria fisica. - Il codice di colorazione delle pagine cerca di evitare l'assegnazione - della pagina 20 perché questa verrebbe mappata sopra lo stesso - blocco di memoria cache della pagina 16 e ciò causerrebbe un uso - non ottimale della cache. - Questo codice aggiunge una complessità significativa - al sottosistema di allocazione memoria della VM, come si può ben - immaginare, ma il gioco vale ben più della candela. La colorazione - delle pagine rende la memoria virtuale deterministica quanto la memoria - fisica per quel che riguarda le prestazioni della cache.</para> - </sect1> - - <sect1 id="conclusion"> - <title>Conclusione</title> - - <para>La memoria virtuale nei sistemi operativi moderni deve affrontare - molti problemi differenti efficientemente e per molti diversi tipi di uso. - L'approccio modulare ed algoritmico che BSD ha storicamente seguito ci - permette di studiare e comprendere l'implementazione attuale cosi come di - poter rimpiazzare in maniera relativamente pulita grosse sezioni di - codice. Ci sono stati un gran numero di miglioramenti al sistema della - VM di FreeBSD negli ultimi anni, ed il lavoro prosegue.</para> - </sect1> - - <sect1 id="allen-briggs-qa"> - <title>Sessione Bonus di Domande e Risposte di Allen Briggs - <email>briggs@ninthwonder.com</email></title> - - <qandaset> - <qandaentry> - <question> - <para>Cos'è <quote>l'algoritmo di interleaving</quote> a cui - fai riferimento nell'elenco delle debolezze della gestione dello - swap in FreeBSD 3.X ?</para> - </question> - - <answer> - <para>FreeBSD usa un intervallo tra zone di swap fissato, con un - valore predefinito di 4. Questo significa che FreeBSD riserva - spazio per quattro aree di swap anche se ne hai una sola o due o - tre. Poiché lo swap è intervallato lo spazio di - indirizzamento lineare che rappresenta le <quote>quattro aree di - swap</quote> verrà frammentato se non si possiedono - veramente quattro aree di swap. Ad esempio, se hai due aree di - swap A e B la rappresentazione dello spazio di FreeBSD per - quell'area di swap verrà interrotta in blocchi di 16 - pagine:</para> - - <literallayout>A B C D A B C D A B C D A B C D</literallayout> - - <para>FreeBSD 3.X usa una <quote>lista sequenziale delle - regioni libere </quote> per registrare le aree di swap libere. - L'idea è che grandi blocchi di spazio libero e lineare - possano essere rappresentati con un nodo singolo - (<filename>kern/subr_rlist.c</filename>). - Ma a causa della frammentazione la lista sequenziale risulta - assurdamente frammentata. - Nell'esempio precedente, uno spazio di swap completamente non - allocato farà si che A e B siano mostrati come - <quote>liberi</quote> e C e D come <quote>totalmente - allocati</quote>. Ogni sequenza A-B richiede un nodo per essere - registrato perché C e D sono buchi, dunquei nodi di lista non - possono essere combinati con la sequenza A-B seguente.</para> - - <para>Perché organizziamo lo spazio in intervalli invece di - appiccicare semplicemente le area di swap e facciamo qualcosa di - più carino? Perché è molto più semplice - allocare strisce lineari di uno spazio di indirizzamento ed ottenere - il risultato già ripartito tra dischi multipli piuttosto che - cercare di spostare questa complicazione altrove.</para> - - <para>La frammentazione causa altri problemi. Essendoci una lista - lineare nella serie 3.X, ed avendo una tale quantità di - frammentazione implicita, l'allocazione e la liberazione dello swap - finisce per essere un algoritmo O(N) invece di uno O(1). - Combinalo con altri fattori (attività di swap pesante) - e comincerai a trovarti con livelli di overhead come O(N^2) e - O(N^3), e ciò è male. Il sistema dela serie 3.X - può anche avere necessità di allocare KVM durante - un'operazione di swap per creare un nuovo nodo lista, il che - può portare ad un deadlock se il sistema sta cercando di - liberare pagine nella memoria fisica in un momento di - scarsità di memoria.</para> - - <para>Nella serie 4.X non usiamo una lista sequenziale. Invece usiamo - un albero radicato e mappe di bit di blocchi di swap piuttosto che - nodi lista. - Ci prendiamo il peso di preallocare tutte le mappe di bit richieste - per l'intera area di swap ma ciò finisce per consumare meno - memoria grazie all'uso di una mappa di bit (un bit per blocco) - invece di una lista collegata di nodi. L'uso di un albero radicato - invece di una lista sequenziale ci fornisce una performance quasi - O(1) qualunque sia il livello di frammentazione dell'albero.</para> - </answer> - </qandaentry> - - <qandaentry> - <question> - <para>Non ho capito questo:</para> - - <blockquote> - <para>È importante notare che il sistema della VM di FreeBSD - tenta di separare pagine pulite e sporche per l'espressa ragione di - evitare scritture non necessarie di pagine sporche (che divorano - banda di I/O), e non sposta le pagine tra le varie code - gratuitamente se il sottosistema non viene stressato. Questo - è il motivo per cui dando un <command>systat -vm</command> - vedrai sistemi con contatori della coda di cache bassi e contatori - della coda delle pagine attive molto alti.</para> - </blockquote> - - <para>Come entra in relazione la separazione delle pagine pulite e - sporche (inattive) con la situazione nella quale vediamo contatori - bassi per la coda di cache e valori alti per la coda delle pagine - attive in <command>systat -vm</command>? I dati di systat derivano - da una fusione delle pagine attive e sporche per la coda delle - pagine attive?</para> - </question> - - <answer> - <para>Si, questo può confondere. La relazione è - <quote>obiettivo</quote> contro <quote>realtà</quote>. Il - nostro obiettivo è separare le pagine ma la realtà - è che se non siamo in crisi di memoria, non abbiamo bisogno - di farlo.</para> - - <para>Questo significa che FreeBSD non cercherà troppo di - separare le pagine sporche (coda inattiva) da quelle pulite - (code della cache), ne cercherà di disattivare le pagine - (coda pagine attive -> coda pagine inattive) quando il sistema non - è sotto sforzo, anche se non vengono effettivamente - usate.</para> - </answer> - </qandaentry> - - <qandaentry> - <question> - <para> Nell'esempio di &man.ls.1; / <command>vmstat 1</command>, - alcuni dei page fault non potrebbero essere data page faults - (COW da file eseguibili a pagine private)? Cioè, io mi - aspetterei che i page fault fossero degli zero-fill e dei dati di - programma. O si implica che FreeBSD effettui il pre-COW per i dati - di programma?</para> - </question> - - <answer> - <para>Un fault COW può essere o legato a uno zero-fill o a dati - di programma. - Il meccanismo è lo stesso in entrambi i casi poiché - i dati di programma da copiare sono quasi certamente già - presenti nella cache. E infatti li tratto insieme. FreeBSD non - effettua preventivamentela copia dei dati di programma o lo - zero-fill, <emphasis>effettua</emphasis> la mappatura preventiva - delle pagine che sono presenti nella sua cache.</para> - </answer> - </qandaentry> - - <qandaentry> - <question> - <para>Nella sezione sull'ottimizzazione della tabella delle pagine, - potresti fornire maggiori dettagli su <literal>pv_entry</literal> e - <literal>vm_page</literal> (forse vm_page dovrebbe essere - <literal>vm_pmap</literal>—come in 4.4, cf. pp. 180-181 di - McKusick, Bostic, Karel, Quarterman)? Specificamente, che tipo di - operazioni/reazioni richiederebbero la scansione delle - mappature?</para> - - <para>Come funziona Linux nel caso in cui FreeBSD fallisce - (la condivisione di un grosso file mappato tra molti - processi)?</para> - </question> - - <answer> - <para>Una <literal>vm_page</literal> rappresenta una tupla - (oggetto,indice#). - Una <literal>pv_entry</literal> rappresenta una voce nella tabella - delle pagine hardware (pte). Se hai cinque processi che condividono - la stessa pagina fisica, e tre delle tabelle delle pagine di questi - processi mappano effettivamente la pagina, questa pagina - verrà rappresentata da una struttura - <literal>vm_page</literal> singola e da tre strutture - <literal>pv_entry</literal>.</para> - - <para>Le strutture <literal>pv_entry</literal> rappresentano solo - le pagine mappate dalla MMU (una <literal>pv_entry</literal> - rappresenta un pte). Ciò significa che è necessario - rimuovere tutti i riferimenti hardware a <literal>vm_page</literal> - (in modo da poter riutilizzare la pagina per qualcos'altro, - effettuare il page out, ripulirla, sporcarla, e così via) - possiamo semplicemente scansionare la lista collegata di - <literal>pv_entry</literal> associate con quella - <literal>vm_page</literal> per rimuovere o modificare i pte - dalla loro tabella delle pagine.</para> - - <para>Sotto Linux non c'è una lista collegata del genere. Per - poter rimuovere tutte le mappature della tabella delle pagine - hardware per una <literal>vm_page</literal> linux deve indicizzare - ogni oggetto VM che <emphasis>potrebbe</emphasis> aver mappato la - pagina. Ad esempio, se si hanno 50 processi che mappano la stessa - libreria condivisa e si vuole liberarsi della pagina X in quella - libreria, sarà necessario cercare nella tabella delle pagine - per ognuno dei 50 processi anche se solo 10 di essi ha - effettivamente mappato la pagina. Così Linux sta barattando - la semplicità del design con le prestazioni. Molti algoritmi - per la VM che sono O(1) o (piccolo N) in FreeBSD finiscono per - diventare O(N), O(N^2), o anche peggio in Linux. - Poiché i pte che rappresentano una particolare pagina in un - oggetto tendono ad essere allo stesso offset in tutte le tabelle - delle pagine nelle quali sono mappati, la riduzione del numero di - accessi alla tabela delle pagine allo stesso offset eviterà - che la la linea di cache L1 per quell'offset venga cancellata, - portando ad una performance migliore.</para> - - <para>FreeBSD ha aggiunto complessità (lo schema - <literal>pv_entry</literal>) in modo da incrementare le prestazioni - (per limitare gli accessi alla tabella delle pagine - <emphasis>solo</emphasis> a quelle pte che necessitino di essere - modificate).</para> - - <para>Ma FreeBSD ha un problema di scalabilità che linux non ha - nell'avere un numero limitato di strutture - <literal>pv_entry</literal> e questo provoca problemi quando si - hanno condivisioni massicce di dati. In questo caso c'è la - possibilità che finiscano le strutture - <literal>pv_entry</literal> anche se c'è ancora una grande - quantità di memoria disponibile. - Questo può essere risolto abbastanza facilmente - aumentando il numero di struttre <literal>pv_entry</literal> nella - configurazione del kernel, ma c'è veramente bisogno di - trovare un modo migliore di farlo.</para> - - <para>Riguardo il sovrapprezzo in memoria di una tabella delle pagine - rispetto allo schema delle <literal>pv_entry</literal>: Linux usa - tabelle delle pagine <quote>permanenti</quote> che non vengono - liberate, ma non necessita una <literal>pv_entry</literal> per ogni - pte potenzialmente mappato. - FreeBSD usa tabelle delle pagine <quote>throw away</quote>, - eliminabili, ma aggiunge una struttura <literal>pv_entry</literal> - per ogni pte effettivamente mappato. Credo che l'utilizzo della - memoria finisca per essere più o meno lo stesso, fornendo a - FreeBSD un vantaggio algoritmico con la capacità di - eliminare completamente le tabelle delle pagine con un - sovraccarico prestazionale minimo.</para> - </answer> - </qandaentry> - - <qandaentry> - <question> - <para>Infine, nella sezione sulla colorazione delle pagine, potrebbe - esser d'aiuto avere qualche descrizione in più di quello che - intendi. Non sono riuscito a seguire molto bene.</para> - </question> - - <answer> - <para>Sai come funziona una memoria cache hardware L1? Spiego: - Considera una macchina con 16MB di memoria principale ma solo 128K - di cache L1. In genere il modo in cui funziona la cache è - che ogni blocco da 128K di memoria principale usa gli - <emphasis>stessi</emphasis> 128K di cache. - Se si accede all'offset 0 della memoria principale e poi al 128K si - può finire per cancellare i dati che si erano messi nella - cache dall'offset 0!</para> - - <para>Ora, sto semplificando di molto. Ciò che ho appena - descritto è quella che viene detta memoria cache a - <quote>corrispondenza diretta</quote>, o direct mapped. - La maggior parte delle cache moderne sono quelle che - vengono dette set-associative a 2 o 4 vie. - L'associatività di questo tipo permette di accedere fino ad N - regioni di memoria differenti che si sovrappongano sulla stessa - cache senza distruggere i dati preventivamente immagazzinati. - Ma solo N.</para> - - <para>Dunque se ho una cache set associativa a 4 vie posso accedere - agli offset 0, 128K, 256K 384K ed essere ancora in grado di - accedere all'offset 0 ritrovandolo nella cache L1. Se poi accedessi - all'offset 512K, ad ogni modo, uno degli oggetti dato immagazzinati - precedentemente verrebbero cancellati dalla cache.</para> - - <para>È estremamente importante … - <emphasis>estremamente</emphasis> importante che la maggior parte - degli accessi del processore alla memoria vengano dalla cache L1, - poiché la cache L1 opera alla stessa frequenza del - processore. Nel momento in cui si ha un miss <footnote> - <para>Un miss nella cache è equivalente a un page fault per - la memoria fisica, ed allo stesso modo implica un accesso a - dispositivi molto più lenti, da L1 a L2 come da RAM a - disco.</para> - </footnote> nella cache L1 si deveandare a cercare nella cache L2 o - nella memoria principale, il processore andrà in stallo, e - potenzialmente potrà sedersi a girarsi i pollici per un tempo - equivalente a <emphasis>centinaia</emphasis> di istruzioni - attendendo che la lettura dalla memoria principale venga - completata. La memoria principale (la RAM che metti nel tuo - computer) è <emphasis>lenta</emphasis>, se comparata alla - velocità del nucleo di un moderno processore.</para> - - <para>Ok, ora parliamo della colorazione dele pagine: - tutte le moderne cache sono del tipo noto come cache - <emphasis>fisiche</emphasis>. Esse memorizzano indirizzi di memoria - fisica, non indirizzi di memoria virtual. Ciò permette alla - cache di rimanere anche nel momento in cui ci sia un cambio di - contesto tra processi, e ciò è molto - importante.</para> - - <para>Ma nel mondo &unix; devi lavorare con spazi di indirizzamento - virtuali, non con spazi di indirizzamento fisici. Ogni programma - che scrivi vedrà lo spazio di indirizzamento virtuale - assegnatogli. Le effettive pagine <emphasis>fisiche</emphasis> - nascoste sotto quello spazio di indirizzi virtuali - non saranno necessariamente contigue fisicamente! In effetti, - potresti avere due pagine affiancate nello spazio di - indirizzamento del processo cge finiscono per trovarsi agli - offset 0 e 128K nella memoria <emphasis>fisica</emphasis>.</para> - - <para>Un programma normalmente assume che due pagine - affiancate verranno poste in cache in maniera ottimale. - Cioè, che possa accedere agli oggetti dato in - entrambe le pagine senza che esse si cancellino a vicenda le - rispettiva informazioni in cache. - Ma ciò è vero solo se le pagine fisiche sottostanti lo - spazio di indirizzo virtuale sono contigue (per quel che riguarda - la cache).</para> - - <para>Questo è ciò che viene fatto dalla colorazione - delle pagine. - Invece di assegnare pagine fisiche <emphasis>casuali</emphasis> agli - indirizzi virtuali, che potrebbe causare prestazioni non ottimali - della cache, la colorazione dele pagine assegna pagine fisiche - <emphasis>ragionevolmente contigue</emphasis>. - Dunque i programmi possono essere scritti assumendo che - le caratteristiche per lo spazio di indirizzamento virtuale del - programma della cache hardware sottostante siano uguali a come - sarebbero state se avessero usato lo spazio di indirizzamento - fisico.</para> - - <para>Si note ho detto <quote>ragionevolmente</quote> contigue invece - che semplicemente <quote>contigue</quote>. Dal punto di vista di - una cache di 128K a corrispondenza diretta, l'indirizzo fisico 0 - è lo stesso che l'indirizzo fisico 128K. - Dunque due agine affiancate nello spzio di indirizzamento virtuale - potrebbero finire per essere all'offset 128K e al 132K nella memoria - fisica, ma potrebbero trovarsi tranquillamente anche agli offset - 128K e 4K della memoria fisica e mantenera comunque le stesse - caratteristiche prestazionali nei riguardi della cache. Dunque la - colorazione delle pagine <emphasis>non</emphasis> deveassegnare - pagine di memoria fisica veramente contigue a pagine di memoria - virtuale contigue, deve solo assicurarsi che siano assegnate pagine - contigue dal punto di vista delle prestazioni/operazioni della - cache.</para> - </answer> - </qandaentry> - </qandaset> - </sect1> -</article> |