aboutsummaryrefslogtreecommitdiff
path: root/it_IT.ISO8859-15/articles/vm-design
diff options
context:
space:
mode:
authorTom Rhodes <trhodes@FreeBSD.org>2003-03-19 19:05:26 +0000
committerTom Rhodes <trhodes@FreeBSD.org>2003-03-19 19:05:26 +0000
commit7ddf4cfda03e141beaf00d5c49e5ba6084192daf (patch)
tree9c12039a081db48e9efeee3d648e83eb47ba1bc2 /it_IT.ISO8859-15/articles/vm-design
parent1930e355407cde9fbc45a788fb99e4217978ff6a (diff)
downloaddoc-7ddf4cfda03e141beaf00d5c49e5ba6084192daf.tar.gz
doc-7ddf4cfda03e141beaf00d5c49e5ba6084192daf.zip
Add a recently translated article: vm-design.
Submitted by: Alex Dupre <sysadmin@alexdupre.com>
Notes
Notes: svn path=/head/; revision=16303
Diffstat (limited to 'it_IT.ISO8859-15/articles/vm-design')
-rw-r--r--it_IT.ISO8859-15/articles/vm-design/Makefile19
-rw-r--r--it_IT.ISO8859-15/articles/vm-design/article.sgml1045
2 files changed, 1064 insertions, 0 deletions
diff --git a/it_IT.ISO8859-15/articles/vm-design/Makefile b/it_IT.ISO8859-15/articles/vm-design/Makefile
new file mode 100644
index 0000000000..0f7f75528a
--- /dev/null
+++ b/it_IT.ISO8859-15/articles/vm-design/Makefile
@@ -0,0 +1,19 @@
+# $FreeBSD$
+
+DOC?= article
+
+FORMATS?= html
+
+IMAGES = ../../../en_US.ISO8859-1/articles/vm-design/fig1.eps
+IMAGES+= ../../../en_US.ISO8859-1/articles/vm-design/fig2.eps
+IMAGES+= ../../../en_US.ISO8859-1/articles/vm-design/fig3.eps
+IMAGES+= ../../../en_US.ISO8859-1/articles/vm-design/fig4.eps
+
+INSTALL_COMPRESSED?=gz
+INSTALL_ONLY_COMPRESSED?=
+
+SRCS= article.sgml
+
+DOC_PREFIX?= ${.CURDIR}/../../..
+
+.include "${DOC_PREFIX}/share/mk/doc.project.mk" \ No newline at end of file
diff --git a/it_IT.ISO8859-15/articles/vm-design/article.sgml b/it_IT.ISO8859-15/articles/vm-design/article.sgml
new file mode 100644
index 0000000000..9f702d49c9
--- /dev/null
+++ b/it_IT.ISO8859-15/articles/vm-design/article.sgml
@@ -0,0 +1,1045 @@
+<!--
+ The FreeBSD Italian Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.11
+-->
+
+<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
+<!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN">
+%man;
+<!ENTITY % translators PUBLIC "-//FreeBSD//ENTITIES DocBook Translator Entities//IT">
+%translators;
+]>
+
+<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>
+
+ <abstract>
+ <para>Il titolo &egrave; in realt&agrave; solo un modo complicato per dire
+ che cercher&ograve; 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&ugrave; 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 &egrave; stata
+ quella del sottosistema di swap.
+ La maggior parte del mio lavoro &egrave; 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&eacute; non sono uno storico come Kirk non
+ tenter&ograve; di marcare tutte le varie caratteristiche con i nomi
+ delle relative persone, perch&eacute; sbaglierei
+ invariabilmente.</para>
+
+ <para>Traduzione a cura di &a.it.surrender;.</para>
+ </abstract>
+
+ <legalnotice>
+ <para>Questo articolo &egrave; stato pubblicato in origine nel numero di
+ gennaio 2000 di <ulink
+ url="http://www.daemonnews.org/">DaemonNews</ulink>.
+ Questa versione dell'articolo pu&ograve; includere aggiornamenti da
+ parte di Matt e di altri autori per riflettere i cambiamenti
+ nell'implementazione della VM di FreeBSD.</para>
+ </legalnotice>
+ </articleinfo>
+
+ <sect1>
+ <title>Introduzione</title>
+
+ <para>Prima di andare avanti con la descrizione del progetto effettivo
+ della VM spendiamo un po' di tempo sulla necessit&agrave; di mantenere
+ e modernizzare una qualunque base di codice longeva.
+ Nel mondo della programmazione, gli algoritmi tendono ad essere pi&ugrave;
+ importanti del codice ed &egrave; dovuto alle radici accademiche
+ di BSD che si &egrave; 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&ograve; 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 &egrave; evoluta, e FreeBSD &egrave; all'avanguardia,
+ non importa quanto possa essere vecchio qualche pezzo di codice.
+ Questa &egrave; una distinzione importante da fare ed una di quelle che
+ sfortunatamente sfuggono alla maggior parte delle persone. Il pi&ugrave;
+ grande errore che un programmatore possa fare &egrave; non imparare
+ dalla storia, e questo &egrave; precisamente l'errore che molti sistemi
+ operativi moderni hanno commesso. NT &egrave; il miglior esempio
+ di questo, e le conseguenze sono state disastrose. Anche Linux commette
+ questo errore a un certo livello&mdash;abbastanza perch&eacute; noi
+ appassionati di BSD possiamo scherzarci su ogni tanto, comunque.
+ Il problema di Linux &egrave; semplicemente la mancanza di esperienza e
+ di una storia con la quale confrontare le idee, un problema che sta
+ venendo affrontato rapidamente dalla comunit&agrave; Linux nello stesso
+ modo in cui &egrave; stato affrontato da quella BSD&mdash;con il continuo
+ sviluppo di codice. La gente di NT, 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 &egrave; stato progettato
+ qui</quote> e di <quote>abbiamo sempre ragione perch&eacute; il nostro
+ dipartimento marketing dice cos&igrave;</quote>. Io ho pochissima
+ tolleranza per chiunque non impari dalla storia.</para>
+
+ <para>La maggior parte dell'apparente complessit&agrave; di progettazione di
+ FreeBSD, specialmente nel sottosistema VM/Swap, &egrave; 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&ugrave; 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&ugrave; importante nel design prestazionale &egrave; ci&ograve; che
+ &egrave; noto come <quote>Ottimizzazione del Percorso Critico</quote>.
+ Accade spesso che le ottimizzazioni prestazionali aggiungano
+ un po di impurit&agrave; 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&ograve; alla fin fine essere pi&ugrave; lento di un sistema
+ pesantemente ottimizzato quando vengono implementati inizialmente, il
+ progetto generalizzato tende ad essere pi&ugrave; semplice da adattare
+ alle condizioni variabili mentre quello pesantemente ottimizzato finisce
+ per dover essere gettato via. Ogni base di codice che dovr&agrave;
+ sopravvivere ed essere mantenibile per anni deve dunque essere progettata
+ con attenzione fin dall'inizio anche se questo pu&ograve; 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&eacute;
+ si poteva produrre codice che era dieci volte pi&ugrave; veloce. Oggi,
+ la fallacia di tale argomento &egrave; ovvia&mdash;cos&igrave; come i
+ paralleli con il design algoritmico e la generalizzazione del
+ codice.</para>
+ </sect1>
+
+ <sect1>
+ <title>Oggetti VM</title>
+
+ <para>Il modo migliore per iniziare a descrivere il sistema di VM di FreeBSD
+ &egrave; 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 &egrave; stato
+ eseguito), ma il codice di programma &egrave; 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 &egrave; 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 &egrave; 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&agrave;
+ gi&agrave; data.</para>
+
+ <para>Una pagina di dati di un programma (che &egrave; una basilare pagina
+ copy-on-write) illustra questa complessit&agrave;. 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&eacute; la copia privata &egrave; stata modificata, il
+ sistema della VM non pu&ograve; pi&ugrave; liberarlo, poich&eacute; non ci
+ sarebbe pi&ugrave; nessuna possibilit&agrave; di recuperarlo in
+ seguito.</para>
+
+ <para>Noterai immediatamente che quella che in origine era soltanto
+ una semplice mappatura di un file &egrave; diventata qualcosa di
+ pi&ugrave; complesso.
+ I dati possono essere modificati pagina per pagina
+ mentre una mappatura di file coinvolge molte pagine alla volta.
+ La complessit&agrave; aumenta ancora quando un processo esegue una fork.
+ Quando un processo esegue una fork, il risultato sono due
+ processi&mdash;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&eacute; &egrave; abbastanza probabile che almeno uno dei due
+ processi avr&agrave; 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&eacute; 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&ograve; con un modello a strati di oggetti
+ VM. Il file binario originale del programma risulta come lo strato di
+ Oggetti VM pi&ugrave; 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&agrave; di copiarla da un livello
+ pi&ugrave; lento. Ad esempio se una pagina di memoria &egrave; 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&ugrave; alto.
+ Quando un processo effettua una fork, vengono aggiunti altri livelli di
+ Oggetti VM. Tutto questo potrebbe avere un po' pi&ugrave; senso con un
+ semplice esempio.
+ Una <function>fork()</function> &egrave; un'operazione comune per ogni
+ sistema *BSD, dunque questo esempio prender&agrave; 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&mdash;le pagine possono essere
+ spostate dentro e fuori dal mezzo fisico del file se necessario.
+ Copiare il file dal disco &egrave; 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&agrave;
+ 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&mdash;C1 per il padre e C2 per il
+ figlio&mdash;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&agrave; un fault di copy-on-write e
+ duplicher&agrave; 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&agrave; un fault di copy-on-write e
+ duplicher&agrave; la pagina in C2.
+ La pagina originale in B &egrave; ora completamente nascosta poich&eacute;
+ 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 &egrave; triviale da
+ realizzare perch&eacute; &egrave; di grana molto fine.
+ FreeBSD non effettua questa ottimizzazione.
+ Ora, supponiamo (come &egrave; spesso il caso) che
+ il processo figlio effettui una <function>exec()</function>. Il suo
+ attuale spazio di indirizzamento &egrave; 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&ograve; 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
+ &egrave; 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&ograve; verificarsi un ingrandimento della
+ pila quando un processo esegue una fork dopo l'altra (che sia il padre o
+ il figlio). Il secondo problema &egrave; che potremmo ritrovarci con
+ pagine morte, inaccessibili nella profondit&agrave; 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 &egrave; pi&ugrave; accessibile
+ da nessuno. Quella pagina in B pu&ograve; essere liberata.</para>
+
+ <para>FreeBSD risolve il problema della profondit&agrave; 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
+ &egrave; 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&ograve; 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 &egrave; accaduto&mdash;ora B ha solo un riferimento
+ (C2), dunque possiamo far collassare B e C2 insieme.
+ Il risultato finale &egrave; 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, &egrave; molto pi&ugrave; probabile che uno dei
+ livelli D sia eventualmente in grado di oscurare completamente l'insieme
+ di dati pi&ugrave; piccolo rappresentato da C1 o C2. La stessa
+ ottimizzazione funzioner&agrave; in ogni punto nel grafico ed il
+ risultato di ci&ograve; &egrave; che anche su una macchina con
+ moltissime fork le pile degli Oggetti VM tendono a non superare una
+ profondit&agrave; di 4. Ci&ograve; &egrave; vero sia per il padre che per
+ il figlio ed &egrave; vero nel caso sia il padre a eseguire la fork ma
+ anche se &egrave; 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&agrave;
+ 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&igrave;
+ &egrave;.</para>
+
+ <para>Il vantaggio del modello ad Oggetti VM &egrave; che
+ <function>fork()</function> &egrave; estremamente veloce, poich&eacute;
+ non deve aver luogo nessuna copia di dati effettiva. Lo svantaggio
+ &egrave; che &egrave; 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>
+ <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&ograve; pi&ugrave; 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 &egrave; 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&mdash;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&eacute; la <quote>lista dei buchi</quote> &egrave; 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 &egrave; ancor pi&ugrave; esacerbato dai buchi creati a causa
+ dell'algoritmo di interleaving.
+ Inoltre il blocco di swap pu&ograve; 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. &Egrave; 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&agrave;
+ 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&ograve; 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 &egrave; 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 &egrave; 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&ugrave; le allocazioni contigue o almeno una localit&agrave;
+ nel riferimento, ma ho assicurato che un'aggiunta simile possa essere
+ effettuata.</para>
+ </sect1>
+
+ <sect1>
+ <title>Quando liberare una pagina</title>
+
+ <para>Poich&eacute; 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&agrave; di
+ scegliere in maniera appropriata le pagine che non sono in uso per
+ riusarle in nuove allocazioni. Selezionare le pagine ottimali da liberare
+ &egrave; forse la funzione singola pi&ugrave; importante che possa essere
+ eseguita da una VM perch&eacute; se si effettua una selezione non
+ accurata, il sistema della VM pu&ograve; 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&agrave; 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 &egrave; 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
+ &egrave; 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&agrave; 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 &egrave; stato di nuovo attivato. Questo indica che la
+ pagina viene ancora usata attivamente.
+ Il bit ancora disattivato &egrave; 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&agrave; 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'&egrave; 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
+ &egrave; in uso pu&ograve; apparire una scelta costosa, in realt&agrave;
+ essa lo &egrave; 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&eacute; le tabelle delle pagine
+ sono entit&agrave; 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
+ &egrave; stata scelta sulla base del contatore d'uso, questo &egrave;
+ 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 &egrave; una pagina sporca, o nella coda di
+ cache se &egrave; 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 &egrave; 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&agrave; bisogno di allocare nuova
+ memoria.</para>
+
+ <para>&Egrave; 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 &egrave; 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&ugrave; efficenti.
+ Per anni &egrave; circolata la leggenda urbana che Linux facesse un lavoro
+ migliore di FreeBSD nell'evitare gli swapout, ma in pratica questo non
+ &egrave; 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>
+ <title>Pre-Faulting e Ottimizzazioni di Azzeramento</title>
+
+ <para>Subire un VM fault non &egrave; costoso se la pagina sottostante
+ &egrave; gi&agrave; nella memoria fisica e deve solo essere mappata di
+ nuovo nel processo, ma pu&ograve; divenire costoso nel caso se ne
+ subiscano un bel po' su base regolare. Un buon esempio di ci&ograve; si
+ ha eseguendo un programma come &man.ls.1; o &man.ps.1; ripetutamente.
+ Se il binario del programma &egrave; 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&ograve; non &egrave; necessario quando le pagine in questione sono
+ gi&agrave; nella cache della VM, quindi FreeBSD tenter&agrave; di
+ pre-popolare le tabelle delle pagine di un processo con quelle pagine che
+ sono gi&agrave; nella VM Cache. Una cosa che FreeBSD non fa ancora
+ &egrave; 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&agrave; di azzerare memoria,
+ non program code fault, legati alla copia dell'eseguibile in memoria
+ (che erano gi&agrave; stati gestiti come pre-fault).
+ Pre-copiare le pagine all'exec o alla fork &egrave; un'area che potrebbe
+ essere soggetta a maggior studio.</para>
+
+ <para>Una larga percentuale dei page fault che accadono &egrave; composta di
+ zero-fill fault. In genere &egrave; 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&eacute; 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&agrave; 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 &egrave; inutilizzata ma il
+ numero di pagine che vengono pre-azzerate dal sistema &egrave; limitato
+ per evitare di spazzare via la cache della memoria. Questo &egrave; un
+ eccellente esempio di complessit&agrave; aggiunta al sistema della VM per
+ ottimizare il percorso critico.</para>
+ </sect1>
+
+ <sect1>
+ <title>Ottimizzazioni della Tabella delle Pagine </title>
+
+ <para>Le ottimizzazioni alla tabella delle pagine costituiscono
+ La parte pi&ugrave; 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 &egrave; stata introdotta
+ la prima volta. Ci sono due ottimizzazioni maggiori. La prima &egrave;
+ 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 &egrave; che ogni pagina attiva nel sistema ha una struttura di
+ controllo <literal>pv_entry</literal> che &egrave; integrata con la
+ struttura <literal>vm_page</literal>. FreeBSD pu&ograve; semplicemente
+ operare attraverso quelle mappature di cui &egrave; 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&ograve; portare ad
+ un sovraccarico computazionale O(n^2) in alcune situazioni.
+ &Egrave; per questo che FreeBSD tende a fare scelte migliori su quale
+ pagina riutilizzare o mandare in swap quando la memoria &egrave; 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&eacute; 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&ugrave;, 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>
+ <title>Colorazione delle Pagine</title>
+
+ <para>Concluderemo con le ottimizzazioni di colorazione delle pagine.
+ La colorazione delle pagine &egrave; 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&egrave; pi&ugrave; 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&agrave; 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 &egrave; attenti pagine affiancate nella memoria
+ virtuale possono finire con l'occupare la stessa pagina nella cache del
+ processore&mdash;portando all'eliminazione prematura di dati
+ immagazzinabili in cache e riducendo le prestazioni della cache.
+ Ci&ograve; &egrave; vero anche con cache set-associative <footnote>
+ <para>set-associative sta per associative all'interno di un insieme, in
+ quanto c'&egrave; 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&ograve; significa che
+ il codice di allocazione della memoria cercher&agrave; di trovare delle
+ pagine libere che siano vicine dal punto di vista della cache.
+ Ad esempio, se la pagina 16 della memoria fisica &egrave; assegnata
+ alla pagina 0 della memoria virtuale di un processo e la cache pu&ograve;
+ contenere 4 pagine, il codice di colorazione delle pagine non
+ assegner&agrave; la pagina 20 di memoria fisica alla pagina 1 di
+ quella virtuale.
+ Invece, gli assegner&agrave; la pagina 21 della memoria fisica.
+ Il codice di colorazione delle pagine cerca di evitare l'assegnazione
+ della pagina 20 perch&eacute; questa verrebbe mappata sopra lo stesso
+ blocco di memoria cache della pagina 16 e ci&ograve; causerrebbe un uso
+ non ottimale della cache.
+ Questo codice aggiunge una complessit&agrave; significativa
+ al sottosistema di allocazione memoria della VM, come si pu&ograve; ben
+ immaginare, ma il gioco vale ben pi&ugrave; 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>
+ <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>
+ <title>Sessione Bonus di Domande e Risposte di Allen Briggs
+ <email>briggs@ninthwonder.com</email></title>
+
+ <qandaset>
+ <qandaentry>
+ <question>
+ <para>Cos'&egrave; <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&eacute; lo swap &egrave; intervallato lo spazio di
+ indirizzamento lineare che rappresenta le <quote>quattro aree di
+ swap</quote> verr&agrave; 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&agrave; 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 &egrave; 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&agrave; 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&eacute; C e D sono buchi, dunquei nodi di lista non
+ possono essere combinati con la sequenza A-B seguente.</para>
+
+ <para>Perch&eacute; organizziamo lo spazio in intervalli invece di
+ appiccicare semplicemente le area di swap e facciamo qualcosa di
+ pi&ugrave; carino? Perch&eacute; &egrave; molto pi&ugrave; semplice
+ allocare strisce lineari di uno spazio di indirizzamento ed ottenere
+ il risultato gi&agrave; 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&agrave; 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&agrave; di swap pesante)
+ e comincerai a trovarti con livelli di overhead come O(N^2) e
+ O(N^3), e ci&ograve; &egrave; male. Il sistema dela serie 3.X
+ pu&ograve; anche avere necessit&agrave; di allocare KVM durante
+ un'operazione di swap per creare un nuovo nodo lista, il che
+ pu&ograve; portare ad un deadlock se il sistema sta cercando di
+ liberare pagine nella memoria fisica in un momento di
+ scarsit&agrave; 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&ograve; 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>&Egrave; 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
+ &egrave; 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&ograve; confondere. La relazione &egrave;
+ <quote>obiettivo</quote> contro <quote>realt&agrave;</quote>. Il
+ nostro obiettivo &egrave; separare le pagine ma la realt&agrave;
+ &egrave; che se non siamo in crisi di memoria, non abbiamo bisogno
+ di farlo.</para>
+
+ <para>Questo significa che FreeBSD non cercher&agrave; troppo di
+ separare le pagine sporche (coda inattiva) da quelle pulite
+ (code della cache), ne cercher&agrave; di disattivare le pagine
+ (coda pagine attive -> coda pagine inattive) quando il sistema non
+ &egrave; 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&egrave;, 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&ograve; essere o legato a uno zero-fill o a dati
+ di programma.
+ Il meccanismo &egrave; lo stesso in entrambi i casi poich&eacute;
+ i dati di programma da copiare sono quasi certamente gi&agrave;
+ 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>&mdash;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&agrave; 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&ograve; significa che &egrave; 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&igrave; 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'&egrave; 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&agrave; necessario cercare nella tabella delle pagine
+ per ognuno dei 50 processi anche se solo 10 di essi ha
+ effettivamente mappato la pagina. Cos&igrave; Linux sta barattando
+ la semplicit&agrave; 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&eacute; 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&agrave;
+ che la la linea di cache L1 per quell'offset venga cancellata,
+ portando ad una performance migliore.</para>
+
+ <para>FreeBSD ha aggiunto complessit&agrave; (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&agrave; 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'&egrave; la
+ possibilit&agrave; che finiscano le strutture
+ <literal>pv_entry</literal> anche se c'&egrave; ancora una grande
+ quantit&agrave; di memoria disponibile.
+ Questo pu&ograve; essere risolto abbastanza facilmente
+ aumentando il numero di struttre <literal>pv_entry</literal> nella
+ configurazione del kernel, ma c'&egrave; 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&ugrave; o meno lo stesso, fornendo a
+ FreeBSD un vantaggio algoritmico con la capacit&agrave; 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&ugrave; 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 &egrave;
+ 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 su
+ pu&ograve; finire per cancellarei dati che si erano messi nella
+ cache dall'offset 0!</para>
+
+ <para>Ora, sto semplificando di molto. Ci&ograve; che ho appena
+ descritto &egrave; 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&agrave; 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>&Egrave; estremamente importante &hellip;
+ <emphasis>estremamente</emphasis> importante che la maggior parte
+ degli accessi del processore alla memoria vengano dalla cache L1,
+ poich&eacute; la cache L1 opera alla stessa frequenza del
+ processore. Nel momento in cui si ha un miss <footnote>
+ <para>Un miss nella cache &egrave; equivalente a un page fault per
+ la memoria fisica, ed allo stesso modo implica un accesso a
+ dispositivi molto pi&ugrave; 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&agrave; in stallo, e
+ potenzialmente potr&agrave; 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) &egrave; <emphasis>lenta</emphasis>, se comparata alla
+ velocit&agrave; 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&ograve; permette alla
+ cache di rimanere anche nel momento in cui ci sia un cambio di
+ contesto tra processi, e ci&ograve; &egrave; 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&agrave; 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&egrave;, che possa accedere agli oggetti dato in
+ entrambe le pagine senza che esse si cancellino a vicenda le
+ rispettiva informazioni in cache.
+ Ma ci&ograve; &egrave; vero solo se le pagine fisiche sottostanti lo
+ spazio di indirizzo virtuale sono contigue (per quel che riguarda
+ la cache).</para>
+
+ <para>Questo &egrave; ci&ograve; 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
+ &egrave; 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>
+
+<!--
+ Local Variables:
+ mode: sgml
+ sgml-indent-data: t
+ sgml-omittag: nil
+ sgml-always-quote-attributes: t
+ End:
+--> \ No newline at end of file