Buffers di I/O
I processi non leggono e scrivono i file accedendovi direttamente su disco; per velocizzare le operazioni vengono usati in memoria dei Buffers di Input e Output.
Buffers in Lettura
Quando un processo richiede la lettura di un certo numero di bytes da un file del disco, il sistema operativo compie un'operazione di lettura fisica di molti più bytes del richiesto e li pone in un buffer in memoria, da cui il processo compie un'operazione di lettura logica. Questa operazione di lettura superiore alla richiesta specifica del processo è chiamata read ahead.
Il costo maggiore delle operazioni su disco è il tempo di seek, ovvero il posizionamento della testina sulla traccia magnetica cercata. Il successivo tempo di I/O è molto piccolo al confronto.
Se il processo sta compiendo operazioni sequenziali di lettura del file, è molto probabile che presto richieda la lettura di altri bytes, che adesso si trovano in memoria.
Migliorare le prestazioni in questo caso consiste nel massimizzare la quantità di operazioni logiche a confronto delle operazioni fisiche.
I programmi che compiono accessi random ai dati su disco non sono invece facilmente ottimizzabili.
Buffers in Scrittura
Avviene l'opposto che in lettura. I processi scrivono subito in buffers in memoria, e solo in un tempo successivo il sistema sincronizza il file su disco col contenuto dei buffers in memoria. Tale strategia si chiama write behind.
I vantaggi sono:
- il buffer può venire cambiato, p.es. da un editor, prima della vera scrittura, evitando così doppie scritture fisiche
- al momento della sincronizzazione più buffers di più processi vengono simultaneamente scritti su disco
- il driver del disco organizza le scritture in modo da compiere un'unica scansione della superficie (operazione di scatter-gather)
L'intervallo tra scritture logiche e fisiche varia casualmente ma può arrivare anche a decine di secondi, tempo molto lungo per il sistema. In generale la scrittura fisica avviene:
- quando i buffers sono pieni
- quando un utente qualsiasi ha dato il comando sync
- quando il file è stato aperto in modalità sincrona
- non esagerare con le aperture sincrone, che rallentano il sistema
- comunque a intervalli regolari
Crash di Sistema
In caso di crash di sistema, p.es. mancanza di alimentazione elettrica, si possono produrre due effetti sfortuna:
- la perdita totale dei buffer in memoria, e la mancanza di aggiornamento dei files corrispondenti aperti su disco
- il crash durante l'aggiornamento e la risistemazione dei blocchi fisici del file, con possibile inconsistenza dell'intero file, fino anche alla sua perdita totale
Il primo effetto è contrastato dalla presenza di una batteria tampone di alimentazione, che dia tempo per una sincronizzazione efficace prima dello shutdown.
Per il secondo effetto esiste, e veniva spesso usato in passato, l'utility fsck (file system check and repair): questa identificava i blocchi orfani e li poneva nella directory lost+found del filesystem, lasciando poi la decisione all'essere umano circa il loro contenuto.
Da molti anni ormai, tutti i file systems usati in Linux e nelle altre varianti di Unix compiono scritture transazionali secondo la sequenza seguente:
- prima della scrittura dei dati avviene una scrittura di tutte le operazioni fisiche da compiersi nel log degli intenti, chiamato anche il journal
- il journal viene sincronizzato. Se c'è un crash a questo punto solo i buffers sono persi e il file rimane consistente.
- viene aggiornato il file vero secondo le indicazioni del journal
In caso di crash, all'atto della risalita del sistema vengono applicate a rovescio le direttive del journal in modo da ripristinare il file alla situazione consistente di prima della scrittura fallita. Avviene cioà quello che è chiamato un rollback.
E' diventato quindi estremamente raro avere files inconsistenti su disco. L'uso del journal introduce una penalità di performance di circa il 10% di tempo di scrittura, ma questo è più che controbilanciato dalla maggiore efficienza hardware dei dischi moderni.
Scrittura su Periferiche Rimuovibili
La scrittura di files su periferiche rimuovibili come chiavette USB sembra procedere con velocità iniziale elevata e con un rallentamento marcato a seguire.
La scrittura è avvenuta inizialmente nei buffer, ma prima di poterla considerare conclusa occorre attendere il completamento della sincronizzazione fisica.
Non compiere la rimozione fisica del dispositivo rimuovibile fino al messaggio che ne indichi il consenso. Il tipico filesystem delle chiavette USB è il VFAT di Windows, che non è transazionale: la rimozione anticipata praticamente garantisce la perdita dei dati, fino all'inaccessibilità dell'intero file system.
E' possibile formattare le chiavette USB con filesystem Linuz, ma non saranno più visibili in Windows. E' anche vero che i file systems NTFS non possono venire letti da Red Hat, per questioni di copyright.
Caches
Il sistema Linux approfitta di ogni occasione per massimizzare l'uso della memoria e minimizzare gli accessi fisici a disco, utilizzando numerose cache.
Vengono soprattutto storati i metadati dei files e le informazioni ottenute da scansioni di directories.
Come effetto visibile l'efficienza operativa di Linux è più elevata dopo un certo tempo dall'accensione. Il sistema è invece relativamente molto lento subito dopo il boot.