Systém správy virtuální paměti ve FreeBSD

26.01.2004 09:33

O FreeBSD se říká, že je to operační systém s nejlepším memory managementem na planetě. Těžko říct co je na tom pravdy, ale je fakt, že oproti některým buranským OS (leehnucks ;)) je systém docela elegantní. Pojďme si ho popsat. Mimochodem předpokládám, že víte co je virtuální paměť, stránkování apod. pokud to nevíte tak go rtfm :-)

FreeBSD spravuje paměť na úrovni stránek. Ty přechovává v queues. Těchto queues je principielně 5 (4 pač wired nemají queue) - podle stavu stránku: wired (stránka která nesmí být odswapována), active (stránka v paměti, která není kandidátem na swapout), inactive (špinavý kandidát na swapout), cache (čistý kandidát na swapout) a free (nealokovaná stránka). V konkrétní implementaci může být těchto queues více. To pokud používáte takzvané barvení stránek. Barvení stránek je nutné pokud máte málo asociativní cache (ie. prestože cache není plná určité dvě stránky se do ní zaráz \"nevejdou\"). Potom je počet queues 4*$počet_barev. Život stránky vypadá asi takto. Je puštěn proces, kterému patří jistá stránka která je v paměti. Ta je umístěna v queue active. Pokud je v systému málo paměti začne zloděj stránek přesouvat stránky z active do inactive/cache (podle toho zda jsou dirty nebo ne). K tomu používá LRU (implementovaný pomocí 1bitového clock algoritmu - tuším se to tak jmenuje). Je nutno si uvědomit, že pokud je stránka v inactive/cache queue referována je její vrácení do systému okamžité. Systém je nastaven tak, že se udržuje jistý poměr mezi počtem stránek v inactive a cache (když se stránka z inactive zapíše na disk je přesunuta do cache). Paměť se alokuje z free a cache queues. Wired stránky jsou prostě zadrátovány a systém na ně kašle.

Dalším aspektem správy paměti v FreeBSD je kdy se vlastně paměť alokuje. FreeBSD implementuje takzvané VM objects. Tyto jsou stackovatelné a je nad nimi definováno několik operací (collapse objects apod.). Každý VM object je s něčím asociován - unbacked (s ničím ;) ), swap-backed, physical-device-backed a file-backed. Pokud tedy spustíme proces vytvoří se VM object popisující tento proces. Tento object bude file-backed (pač soubory spouštíme ze souborů). Pokud např. zapíšeme do BSS sekce programu pak se vytvoří nový object (unbacked, pač jede z paměti) ve kterém bude právě jedna stránka (ta ve které je ta proměnná do které jste zapsali). Tento VM object je stínován původním VM objectem (všechny refernce na stránky které v něm nejsou obsaženy jsou obslouženy stínujícím objectem). Pokud teď provedeme fork() pouze se vytvoří nový VM object, který bude celý stínován původním. Tím je efektivně dosaženo COW. Stejně tak se může vytvořit swap-backed VM object což nám implementuje swap. Protože se VM objecty používají na všechno, tj. používá je i read/write i mmap je dosaženo unified buffer cache (prostě se to bude různě stínovat). Mohlo by se stát, že stack VM objectů bude příliš hluboký a proto FreeBSD implementuje algoritmy které tomuto zabraňují. Dle dokumentace hloubka obvykle nepřesahuje 4.

Když se systém FreeBSD nudí tak koná (mimojiné) několik věcí - nuluje stránky, syncuje stránky, proaktivně swapuje (zapisuje do volného místa do swapu i to co se nemusí - pokud je pak nutno něco odswapovat je to rychlejší). FreeBSD implementuje takzvaný reverse-mapping, tj. uvolnění stránky je O(1) operace. Swap je organizován pomocí bitmapy (také O(1)). Na alokaci kernelové paměti se používa slab-allocator (nejsem si jist rozdílem mezi slab a zone, je to same?) tj. položky jsou seřazeny dle velikosti a vždy se bere z dané kategorie. Položky jsou přednastaveny (kvůli rychlosti).

FreeBSD pozdějších verzí (4 a výše?) je plné různých algoritmů na autonastavování různých parametrů. Proto je docela dobře možné používat FreeBSD takříkajíc out-of-the-box. Abych porovnal FreeBSD s Linuxem tak musím říct, že se mi jeví FreeBSD rychlejší. Ale čísly to podloženo nemám (a navíc mam fbsd daleko líp zkonfigurované/zoptimalizované).

Aby tenhle článeček nebyl tak úplně non-flame tak si na závěr pastneme jednu citaci:
Twenty years ago people were still arguing that programming in assembly was better than programming in a high-level language because it produced code that was ten times as fast. Today, the fallibility of that argument is obvious--as are the parallels to algorithmic design and code generalization.
-- Matthew Dillon (of Amiga and FreeBSD fame)

neologism

P.S. o daném tématu nevím zhola nic, tak mne uflamujte xmrti... ale FreeBSD VM je (ostatne jako cely kernel) velmi citelne - go read src/vm ;) mimochodem, mrknete nekdy na funkci vm_pageout_scan()... mozna pochopite muj nazor na programovani

P.S. kdyz jsem hledal algoritmus urcujici ktera stranka pujde do swapu tak mi to v FreeBSD zabralo asi minutu. V linuxu jsem ji nenasel (mam kandidata, ale je to napsano linuxove, takze tezko rict). mimochodem je to try_to_swap_out() ?neologism