aboutsummaryrefslogtreecommitdiff
path: root/it_IT.ISO8859-15/articles/vm-design/article.xml
diff options
context:
space:
mode:
authorEitan Adler <eadler@FreeBSD.org>2018-08-11 01:23:04 +0000
committerEitan Adler <eadler@FreeBSD.org>2018-08-11 01:23:04 +0000
commit7820081803d64f03e525b5c507176a41c64d3c48 (patch)
treea853a09076bcd918451ac926564fff824fb3e063 /it_IT.ISO8859-15/articles/vm-design/article.xml
parent870a8a1d4da10d876bf11034d23bc16cb3d26982 (diff)
downloaddoc-7820081803d64f03e525b5c507176a41c64d3c48.tar.gz
doc-7820081803d64f03e525b5c507176a41c64d3c48.zip
doc: remove much of the Italian translations
The Italian translation has not been updated since r31375 on 2008-01-27. Future commits were either mechanical or global. - The committers guide still references CVS - The handbook still references sysinstall - Both still reference GNATS In general the documentation is out of date sufficient and not being updated. The hard work of the previous contributors is much appreciated. Leave the handbook as there is interest in continuing the project.
Notes
Notes: svn path=/head/; revision=52099
Diffstat (limited to 'it_IT.ISO8859-15/articles/vm-design/article.xml')
-rw-r--r--it_IT.ISO8859-15/articles/vm-design/article.xml1036
1 files changed, 0 insertions, 1036 deletions
diff --git a/it_IT.ISO8859-15/articles/vm-design/article.xml b/it_IT.ISO8859-15/articles/vm-design/article.xml
deleted file mode 100644
index 1b30d5b48e..0000000000
--- a/it_IT.ISO8859-15/articles/vm-design/article.xml
+++ /dev/null
@@ -1,1036 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-15"?>
-<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
- "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
-<!--
- The FreeBSD Italian Documentation Project
-
- $FreeBSD$
- Original revision: 1.16
--->
-<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="it">
- <info><title>Elementi di progettazione del sistema di VM di FreeBSD</title>
-
-
- <authorgroup>
- <author><personname><firstname>Matthew</firstname><surname>Dillon</surname></personname><affiliation>
- <address>
- <email>dillon@apollo.backplane.com</email>
- </address>
- </affiliation></author>
- </authorgroup>
-
- <legalnotice xml: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 xml:id="legalnotice">
- <para>Questo articolo è stato pubblicato in origine nel numero di
- gennaio 2000 di <link xlink:href="http://www.daemonnews.org/">DaemonNews</link>.
- 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>
- </info>
-
- <sect1 xml: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&mdash;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&mdash;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&mdash;così come i
- paralleli con il design algoritmico e la generalizzazione del
- codice.</para>
- </sect1>
-
- <sect1 xml: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&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é è 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"/>
- </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 è 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"/>
- </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"/>
- </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"/>
- </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-&gt;B-&gt;A e C2-&gt;B-&gt;A adesso
- abbiamo C1-&gt;A e C2-&gt;B-&gt;A.
- ma si noti cos'altro è accaduto&mdash;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-&gt;A e C2-&gt;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 xml: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&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é 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 xml: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 xml: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 xml: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 xml: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&mdash;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 xml: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 xml: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 -&gt; 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>&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à 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 &hellip;
- <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>