- Come garantire le prestazioni del file system?
Come sappiamo benissimo l’accesso al disco è molto più lento di un accesso alla memoria. Per questa differenza di tempo di accesso, in molti file system sono stati progettati diverse ottimizzazioni per migliorare le performance, riducendo al minimo :
- numeri di accessi al disco/SSD
- tempo di ricerca (seek) del dato sul disco/SSD
- utilizzo dello spazio
Infatti tra le ottimizzazioni delle prestazioni abbiamo :
- block cache / buffer cache : utilizzata per ridurre i tempi di accesso al disco, mantenendo i blocchi più usati in memoria
- allocazione intelligente : blocchi vicini nello stesso cilindro per minimizzare il movimento del braccio del disco
- bitmap in memoria per allocare blocchi contigui e migliorare l’efficienza di scrittura sequenziale
- deframmentazione : con il tempo i dischi si frammentano, ovvero che i dati dei file sono sparsi portando a prestazioni inferiori
- con la deframmentazione vengono riorganizzati i file per essere contigui e raggruppa lo spazio libero
- windows offre il tool
defragper questa operazione (consigliato per HDD ma non per SSD)
Caching - block / buffer cache
Per minimizzare gli accessi al disco tramite caching, vengono memorizzati i blocchi del disco in RAM.
- buffer cache (o block cache) : memorizza i blocchi del disco
- page cache : memorizza le pagine del file system virtuale (VFS, vediamo dopo …)
Quando viene richiesta la lettura di un blocco del file :
- verifica nella cache
- se c’è ottimo
- altrimenti, il blocco viene prima letto dal disco, portato nella cache e poi utilizzato
La ricerca del blocco nella cache in modo sequenziale è lento, per questo si usa la tecnica a dizionario/hash, dove viene utilizzata una funzione hash per identificare velocemente la presenza di un blocco nella cache e nel caso di blocchi con lo stesso hash (collisione), vengono messi in una lista concatenata (già visto nel corso di Programmazione) :

Ricerca blocco da sostituire
Un altro problema da considerare è quando la cache diventa piena. In questo caso bisogna scegliere quale blocco sostituirlo e se “sporco” va scritto su disco (insomma come paging).
Algoritmi per il paging come FIFO, FIFO2 e LRU sono applicabili anche qua. L’algoritmo LRU in questo caso utilizza una lista bidirezionale, dove i blocchi sono tenuti in ordine d’uso (- recenti in testa e + recenti in fondo).
Il problema noto del LRU è che guarda solo se il blocco è stato utilizzato meno o poco, non quanto è importante. Questo può portare a inconsistenza in caso di crash (blocco importante non viene mai scritto su disco) sopratutto come blocchi i-node.
La soluzione è un LRU modificato basato anche sull’importanza del blocco e non solo su l’età.
Crash sistema e soluzioni
Inoltre per evitare che un crash ci distrugga i file, il OS interviene con due regole di sicurezza :
- scrittura immediata dei blocchi critici : appena modificati vengono scritti su disco
- scrittura periodica dei blocchi normali :
- in UNIX si usa un daemon che lancia periodicamente la system call
sync, che prende tutti i blocchi modificati che sono nella cache e li riversa su disco
- in UNIX si usa un daemon che lancia periodicamente la system call
La filosofia di Windows era di scrivere immediatamente tutti i blocchi modificati, siccome questo non è efficiente, è stata integrata la chiamata FlushFileBuffers che può essere chiamata dai programmi (decidono loro quando svuotare su disco).
Comando free (Linux)
In Segmentazione abbiamo già incontrato il comando free che ci permette di avere una panoramica dettagliata del utilizzo della RAM, inclusa la cache e lo spazio libero, in particolare :
buff/cache: rileva quanto spazio RAM il sistema sta utilizzando per la cache dei blocchi del discofree: spazio RAM completamente vuotoavailable: colonna che dobbiamo vedere se vogliamo sapere se possiamo far partire un nuovo programma
La differenza tra le due colonne free e available è la seguente :

Deframmentazione del disco
Abbiamo già descritto il problema della frammentazione e la soluzione tramite la deframmentazione.
Facciamo alcune osservazioni :
- la deframmentazione è utile solo nei HDD e non sui SSD (per evitare scritture inutili)
- su Windows il
defragsi usa spesso, ma su Linux non serve quasi mai, siccome utilizza fs come ext3/ext4 che utilizzano la pre-allocazione dei blocchi (vedi Linux_FS)
Mentre se il disco risulta pieno, esistono due tecniche avanzate che permettono al fs di recuperare spazio :
- compressione :
- lavora all’interno dei file
- cerca sequenza di dati che si ripetono e la sostituisce con una formula più prese (es. A A A A A A )
- utilizzato automaticamente da molti fs come NTFS (Win) e Btrfs/ZFS (Linux)
- deduplicazione :
- lavora sull’intero disco
- cerca file o blocchi di dati identici, conservando una sola copia di ciascun dato
- utile nei server dove ci sono dati condivisi
Nella deduplicazione il sistema utilizza un hash per capire se due blocchi dati sono uguali. Il problema è che ci possono essere delle collisioni (rare ma possibili), quindi è necessario un double check per assicurarsi che i due blocchi siano uguali.
