De buffercache

Lezen vanaf een disk [1] is in vergelijking met het benaderen van (echt) geheugen erg langzaam. Bovendien is het heel gewoon om gedurende relatief korte perioden hetzelfde deel van een disk verscheidene malen te lezen. Men zou bijvoorbeeld eerst een e-mail bericht kunnen lezen, vervolgens de brief in een editor kunnen laden om er antwoord op te geven, en het dan nog eens in het mailprogramma in kunnen lezen als het naar een folder wordt gekopieerd. Of overweeg eens hoevaak de opdracht ls op een systeem met meerdere gebruikers zou kunnen worden opgestart. Door de informatie slechts éénmaal vanaf disk in te lezen en het dan in het geheugen te houden totdat het niet langer nodig is, kan het allemaal, behalve de eerste keer dat het wordt ingelezen, worden versneld. Dit wordt disk buffering genoemd, en het geheugen dat voor dit doel wordt gebruikt, wordt de buffer cache genoemd.

Gezien geheugen helaas eindig is, ja zelfs een schaarse bron, kan de buffercache gewoonlijk niet groot genoeg zijn (het kan de data niet vasthouden die men ooit wil gebruiken). Wanneer de cache vol raakt, worden de gegevens die het langst niet zijn gebruikt, verworpen en het geheugen dat is vrij gemaakt wordt gebruikt voor de nieuwe gegevens.

Disk buffering werkt tevens voor het schrijven. Aan de ene kant worden de weggeschreven gegevens vaak spoedig weer ingelezen (b.v. de source code die in een bestand wordt opgeslagen en vervolgens door de compiler wordt ingelezen), dus het in de cache plaatsen van weggeschreven gegevens is een goed plan. Aan de andere kant, door de gegevens alleen in de cache te plaatsen en ze niet onmiddellijk naar disk weg te schrijven, draait het programma dat wegschrijft, sneller. De schrijfopdrachten kunnen dan in de achtergrond worden uitgevoerd, zonder de andere programma's te vertragen.

De meeste besturingssystemen beschikken over buffercaches (alhoewel ze anders genoemd kunnen zijn), maar ze werken niet allen volgens de bovenstaande principes. Een aantal zijn write-through: de data wordt onmiddellijk naar disk weggeschreven (het wordt natuurlijk ook in de cache bewaard). De cache wordt write-back genoemd als de schrijfbewerkingen op een later tijdstip worden uitgevoerd. Write-back is efficiënter dan write-through, maar ook gevoeliger voor fouten: als de machine vastloopt, of de stroom wordt op het verkeerde moment onderbroken, of de diskette wordt uit het diskettestation verwijderd voordat de data in de cache wordt weggeschreven, dan gaat de data in de cache gewoonlijk verloren. Dit kan zelfs betekenen dat het bestandssysteem (als dat er is) niet volledig werkend meer is, wellicht omdat de ongeschreven data belangrijke wijzigingen bevatte voor de administratieve informatie.

Daarom moet je de stroom nooit zomaar uitschakelen zonder eerst een zuivere afsluitprocedure te hebben doorlopen (zie Hoofdstuk 8), of een diskette uit het diskettestation verwijderen voordat het is ontkoppeld (als het werd gemount) of nadat een willekeurig programma dat er gebruik van heeft gemaakt, signaleert dat het klaar is en de led van het diskettestation niet meer oplicht. De opdracht sync leegt de buffer, d.w.z., forceert alle ongeschreven data naar disk weg te schrijven, en het kan worden gebruikt wanneer men er zeker van wil zijn dat alles veilig is weggeschreven. Op traditionele UNIX-systemen, bestaat een programma met de naam update dat als achtergrondproces draait en elke 30 seconden een sync uitvoert. Het is dan niet meer nodig gebruik te maken van sync. Linux heeft daarnaast nog een daemon, bdflush, die een iets onvolmaaktere sync frequenter uitvoert om het plotselingen bevriezen vanwege zwaar disk I/O te voorkomen dat sync soms veroorzaakt.

Onder Linux wordt bdflush gestart door update. Meestal hoef je je hier niet druk om te maken, maar mocht bdflush om wat voor reden dan ook stoppen, dan zal de kernel een waarschuwing geven, en moet je het met de hand weer opstarten (/sbin/update).

In werkelijkheid worden er in de cache geen bestanden gebufferd, maar blokken, wat de kleinste eenheden zijn van disk I/O (ze zijn onder Linux meestal 1 kB). Op deze manier worden ook directory's, superblokken en andere administratieve gegevens van een bestandssysteem en disks zonder bestandssysteem in de cache geplaatst.

De doeltreffendheid van een cache wordt voornamelijk bepaald door de grootte ervan. Een kleine cache is vrijwel nutteloos: het zal zo weinig gegevens bevatten dat alle in de cache geplaatste gegevens uit de cache zullen worden verwijderd nog voor het opnieuw gebruikt kan worden. De kritieke grootte hangt af van de hoeveelheid ingelezen en weggeschreven gegevens, en hoevaak dezelfde gegevens worden benaderd. De enige manier om daar achter te komen, is door ermee te experimenteren.

Als de cache van een vastgestelde grootte is, is het ook niet verstandig dat deze te groot is, omdat het mogelijk is dat het vrije geheugen daardoor te klein zal zijn en het swappen zal veroorzaken (wat ook langzaam is). Om zo efficiënt mogelijk gebruik te maken van het echte geheugen, maakt Linux automatisch van al het vrije RAM gebruik voor de buffer cache, maar het maakt de cache ook kleiner als programma's meer geheugen nodig hebben.

Onder Linux hoef je niets te doen om gebruik te maken van de cache, dit gebeurt volautomatisch. Afgezien van het opvolgen van de juiste procedures voor het afsluiten van het systeem en verwijderen van diskettes, hoef je je er geen zorgen om te maken.

Noten

[1]

Behalve vanaf een RAM disk, om vanzelfsprekende redenen.