From c9c149db16c39efdfa53bde804b7a189dd923eef Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Fri, 27 Mar 2015 12:39:11 +0000 Subject: [PATCH] Piccole correzioni ed inizio della risistemazione degli indici. --- fileadv.tex | 63 ++++++++++++++++++++++++++--------------------------- process.tex | 46 +++++++++++++++++++------------------- 2 files changed, 55 insertions(+), 54 deletions(-) diff --git a/fileadv.tex b/fileadv.tex index 0ef7c30..f955a41 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -3941,7 +3941,6 @@ per la gestione del \textit{memory mapped I/O}, la prima di queste, che serve ad eseguire la mappatura in memoria di un file, è \funcd{mmap}; il suo prototipo è: - \begin{funcproto}{ \fhead{unistd.h} \fhead{sys/mman.h} @@ -3987,7 +3986,7 @@ La funzione richiede di mappare in memoria la sezione del file \param{fd} a partire da \param{offset} per \param{length} byte, preferibilmente all'indirizzo \param{start}. Il valore \param{start} viene normalmente considerato come un suggerimento, ma l'uso di un valore diverso da \val{NULL}, -in cui di rimette completamente al kernel la scelta dell'indirizzo, viene +in cui si rimette completamente al kernel la scelta dell'indirizzo, viene sconsigliato per ragioni di portabilità. Il valore di \param{offset} deve essere un multiplo della dimensione di una pagina di memoria. @@ -4012,8 +4011,8 @@ essere un multiplo della dimensione di una pagina di memoria. Il valore dell'argomento \param{prot} indica la protezione\footnote{come accennato in sez.~\ref{sec:proc_memory} in Linux la memoria reale è divisa - in pagine: ogni processo vede la sua memoria attraverso uno o più segmenti - lineari di memoria virtuale. Per ciascuno di questi segmenti il kernel + in pagine, ogni processo vede la sua memoria attraverso uno o più segmenti + lineari di memoria virtuale; per ciascuno di questi segmenti il kernel mantiene nella \itindex{page~table} \textit{page table} la mappatura sulle pagine di memoria reale, ed le modalità di accesso (lettura, esecuzione, scrittura); una loro violazione causa quella una \itindex{segment~violation} @@ -4062,7 +4061,8 @@ tab.~\ref{tab:file_mmap_flag}. \const{MAP\_GROWSDOWN} & Usato per gli \itindex{stack} \textit{stack}. Indica che la mappatura deve essere effettuata con gli indirizzi crescenti verso il basso.\\ - \const{MAP\_HUGETLB} & da trattare (dal 2.6.32).\\ + \const{MAP\_HUGETLB} & Esegue la mappatura usando le cosiddette + ``\textit{huge pages}'' (dal 2.6.32).\\ \const{MAP\_LOCKED} & Se impostato impedisce lo swapping delle pagine mappate (dal 2.5.37).\\ \const{MAP\_NONBLOCK} & Esegue un \textit{prefaulting} più limitato che @@ -4070,17 +4070,15 @@ tab.~\ref{tab:file_mmap_flag}. \const{MAP\_NORESERVE} & Si usa con \const{MAP\_PRIVATE}. Non riserva delle pagine di swap ad uso del meccanismo del \textit{copy on write} \itindex{copy~on~write} - per mantenere le - modifiche fatte alla regione mappata, in - questo caso dopo una scrittura, se non c'è più - memoria disponibile, si ha l'emissione di - un \signal{SIGSEGV}.\\ + per mantenere le modifiche fatte alla regione + mappata, in questo caso dopo una scrittura, se + non c'è più memoria disponibile, si ha + l'emissione di un \signal{SIGSEGV}.\\ \const{MAP\_PRIVATE} & I cambiamenti sulla memoria mappata non vengono riportati sul file. Ne viene fatta una copia privata cui solo il processo chiamante ha accesso. Le modifiche sono mantenute attraverso - il meccanismo del \textit{copy on - write} \itindex{copy~on~write} e + il meccanismo del \textit{copy on write} e salvate su swap in caso di necessità. Non è specificato se i cambiamenti sul file originale vengano riportati sulla regione @@ -4477,38 +4475,39 @@ partire dal quale la sezione di file indicata verrà rimappata. L'argomento valori di \func{mmap} (quelli di tab.~\ref{tab:file_mmap_prot}) ma di tutti i flag solo \const{MAP\_NONBLOCK} non viene ignorato. +\itindbeg{prefaulting} + Insieme alla funzione \func{remap\_file\_pages} nel kernel 2.5.46 con sono stati introdotti anche due nuovi flag per \func{mmap}: \const{MAP\_POPULATE} e \const{MAP\_NONBLOCK}. Il primo dei due consente di abilitare il meccanismo -del \itindex{prefaulting} \textit{prefaulting}. Questo viene di nuovo in aiuto -per migliorare le prestazioni in certe condizioni di utilizzo del -\textit{memory mapping}. +del \textit{prefaulting}. Questo viene di nuovo in aiuto per migliorare le +prestazioni in certe condizioni di utilizzo del \textit{memory mapping}. Il problema si pone tutte le volte che si vuole mappare in memoria un file di -grosse dimensioni. Il comportamento normale del sistema della -\index{memoria~virtuale} memoria virtuale è quello per cui la regione mappata -viene aggiunta alla \itindex{page~table} \textit{page table} del processo, ma -i dati verranno effettivamente utilizzati (si avrà cioè un -\itindex{page~fault} \textit{page fault} che li trasferisce dal disco alla -memoria) soltanto in corrispondenza dell'accesso a ciascuna delle pagine -interessate dal \textit{memory mapping}. +grosse dimensioni. Il comportamento normale del sistema della memoria virtuale +è quello per cui la regione mappata viene aggiunta alla \textit{page table} +del processo, ma i dati verranno effettivamente utilizzati (si avrà cioè un +\textit{page fault} che li trasferisce dal disco alla memoria) soltanto in +corrispondenza dell'accesso a ciascuna delle pagine interessate dal +\textit{memory mapping}. Questo vuol dire che il passaggio dei dati dal disco alla memoria avverrà una pagina alla volta con un gran numero di \itindex{page~fault} \textit{page fault}, chiaramente se si sa in anticipo che il file verrà utilizzato -immediatamente, è molto più efficiente eseguire un \itindex{prefaulting} -\textit{prefaulting} in cui tutte le pagine di memoria interessate alla -mappatura vengono ``\textsl{popolate}'' in una sola volta, questo -comportamento viene abilitato quando si usa con \func{mmap} il flag -\const{MAP\_POPULATE}. +immediatamente, è molto più efficiente eseguire un \textit{prefaulting} in cui +tutte le pagine di memoria interessate alla mappatura vengono +``\textsl{popolate}'' in una sola volta, questo comportamento viene abilitato +quando si usa con \func{mmap} il flag \const{MAP\_POPULATE}. Dato che l'uso di \const{MAP\_POPULATE} comporta dell'I/O su disco che può rallentare l'esecuzione di \func{mmap} è stato introdotto anche un secondo -flag, \const{MAP\_NONBLOCK}, che esegue un \itindex{prefaulting} -\textit{prefaulting} più limitato in cui vengono popolate solo le pagine della -mappatura che già si trovano nella cache del kernel.\footnote{questo può - essere utile per il linker dinamico, in particolare quando viene effettuato - il \textit{prelink} delle applicazioni.} +flag, \const{MAP\_NONBLOCK}, che esegue un \textit{prefaulting} più limitato +in cui vengono popolate solo le pagine della mappatura che già si trovano +nella cache del kernel.\footnote{questo può essere utile per il linker + dinamico, in particolare quando viene effettuato il \textit{prelink} delle + applicazioni.} + +\itindend{prefaulting} Per i vantaggi illustrati all'inizio del paragrafo l'interfaccia del \textit{memory mapped I/O} viene usata da una grande varietà di programmi, diff --git a/process.tex b/process.tex index ec40d30..307ab48 100644 --- a/process.tex +++ b/process.tex @@ -638,16 +638,17 @@ programma in esecuzione, e le varie funzioni utilizzabili per la sua gestione. \subsection{I concetti generali} \label{sec:proc_mem_gen} +\index{memoria~virtuale|(} + Ci sono vari modi in cui i sistemi operativi organizzano la memoria, ed i dettagli di basso livello dipendono spesso in maniera diretta dall'architettura dell'hardware, ma quello più tipico, usato dai sistemi -unix-like come Linux è la cosiddetta \index{memoria~virtuale} \textsl{memoria - virtuale} che consiste nell'assegnare ad ogni processo uno spazio virtuale -di indirizzamento lineare, in cui gli indirizzi vanno da zero ad un qualche -valore massimo.\footnote{nel caso di Linux fino al kernel 2.2 detto massimo - era, per macchine a 32bit, di 2Gb. Con il kernel 2.4 ed il supporto per la - \textit{high-memory} il limite è stato esteso anche per macchine a 32 bit.} - +unix-like come Linux è la cosiddetta \textsl{memoria virtuale} che consiste +nell'assegnare ad ogni processo uno spazio virtuale di indirizzamento lineare, +in cui gli indirizzi vanno da zero ad un qualche valore massimo.\footnote{nel + caso di Linux fino al kernel 2.2 detto massimo era, per macchine a 32bit, di + 2Gb. Con il kernel 2.4 ed il supporto per la \textit{high-memory} il limite + è stato esteso anche per macchine a 32 bit.} Come accennato nel cap.~\ref{cha:intro_unix} questo spazio di indirizzi è virtuale e non corrisponde all'effettiva posizione dei dati nella RAM del @@ -683,17 +684,17 @@ della funzione \func{printf} starà su una sola pagina di memoria reale che farà da supporto a tutte le pagine di memoria virtuale di tutti i processi che hanno detta funzione nel loro codice. -La corrispondenza fra le pagine della \index{memoria~virtuale} memoria -virtuale di un processo e quelle della memoria fisica della macchina viene -gestita in maniera trasparente dal kernel.\footnote{in genere con l'ausilio - dell'hardware di gestione della memoria (la \textit{Memory Management Unit} - del processore), con i kernel della serie 2.6 è comunque diventato possibile - utilizzare Linux anche su architetture che non dispongono di una MMU.} -Poiché in genere la memoria fisica è solo una piccola frazione della memoria -virtuale, è necessario un meccanismo che permetta di trasferire le pagine che -servono dal supporto su cui si trovano in memoria, eliminando quelle che non -servono. Questo meccanismo è detto \index{paginazione} \textsl{paginazione} -(o \textit{paging}), ed è uno dei compiti principali del kernel. +La corrispondenza fra le pagine della memoria virtuale di un processo e quelle +della memoria fisica della macchina viene gestita in maniera trasparente dal +kernel.\footnote{in genere con l'ausilio dell'hardware di gestione della + memoria (la \textit{Memory Management Unit} del processore), con i kernel + della serie 2.6 è comunque diventato possibile utilizzare Linux anche su + architetture che non dispongono di una MMU.} Poiché in genere la memoria +fisica è solo una piccola frazione della memoria virtuale, è necessario un +meccanismo che permetta di trasferire le pagine che servono dal supporto su +cui si trovano in memoria, eliminando quelle che non servono. Questo +meccanismo è detto \index{paginazione} \textsl{paginazione} (o +\textit{paging}), ed è uno dei compiti principali del kernel. Quando un processo cerca di accedere ad una pagina che non è nella memoria reale, avviene quello che viene chiamato un \itindex{page~fault} \textit{page @@ -716,6 +717,7 @@ esigenze specifiche di prestazioni è possibile usare delle funzioni che permettono di bloccare il meccanismo della \index{paginazione} paginazione e mantenere fisse delle pagine in memoria (vedi sez.~\ref{sec:proc_mem_lock}). +\index{memoria~virtuale|)} \subsection{La struttura della memoria di un processo} \label{sec:proc_mem_layout} @@ -730,10 +732,10 @@ un'associazione nella memoria virtuale, il kernel risponde al relativo \itindex{page~fault} \textit{page fault} mandando un segnale \signal{SIGSEGV} al processo, che normalmente ne causa la terminazione immediata. -È pertanto importante capire come viene strutturata \index{memoria~virtuale} -la memoria virtuale di un processo. Essa viene divisa in \textsl{segmenti}, -cioè un insieme contiguo di indirizzi virtuali ai quali il processo può -accedere. Solitamente un programma C viene suddiviso nei seguenti segmenti: +È pertanto importante capire come viene strutturata la memoria virtuale di un +processo. Essa viene divisa in \textsl{segmenti}, cioè un insieme contiguo di +indirizzi virtuali ai quali il processo può accedere. Solitamente un +programma C viene suddiviso nei seguenti segmenti: \begin{enumerate*} \item Il \index{segmento!testo} segmento di testo o \textit{text segment}. Contiene il codice del programma, delle funzioni di librerie da esso -- 2.30.2