Mapování paměti souboru přímo zabraňuje kopírování vyrovnávacích pamětí, ke kterému dochází s read()
a write()
hovory. Volání na read()
a write()
zahrnout ukazatel na vyrovnávací paměť v adresovém prostoru procesu, kde jsou data uložena. Kernel musí kopírovat data do/z těchto umístění. Pomocí mmap()
mapuje soubor na adresní prostor procesu, takže proces může adresovat soubor přímo a nejsou vyžadovány žádné kopie.
Při přístupu k souboru mapovanému do paměti po úvodním volání také nevzniká žádná režie systémového volání, pokud je soubor načten do paměti na počátečním mmap()
. Pokud stránka mapovaného souboru není v paměti, přístup vygeneruje chybu a bude vyžadovat, aby jádro načetlo stránku do paměti. Čtení velkého bloku s read()
může být rychlejší než mmap()
v takových případech, pokud mmap()
by generovalo značný počet chyb při čtení souboru. (Je možné doporučit jádru předem s madvise()
aby jádro mohlo načíst stránky s předstihem před přístupem).
Pro více podrobností je zde související otázka o Stack Overflow:mmap() vs. bloky čtení
Za prvé, ve většině operací IO vlastnosti základního hardwaru úložiště dominují výkonu. Špatně nakonfigurované pole RAID5 dvaceti devíti disků S-L-O-W 5400 ot./min SATA na pomalém systému s nedostatkem paměti využívající S/W RAID s neodpovídajícími velikostmi bloků a špatně zarovnanými systémy souborů vám poskytne slabý výkon ve srovnání se správně nakonfigurovaným a zarovnaným SSD RAID 1+0 na vysoce výkonném řadiči bez ohledu na jakékoli softwarové ladění, které byste mohli zkusit.
Ale jediný způsob mmap()
může být výrazně rychlejší, pokud čtete stejná data více než jednou a data, která čtete, nejsou mezi čteními stránkována kvůli tlaku paměti.
Kroky mapy paměti:
- Systémové volání k vytvoření virtuálních mapování – velmi drahé
- Proces poprvé přistupuje k paměti, což způsobuje chybu stránky – drahé (a může být nutné opakovat, pokud je stránkováno)
- Proces skutečně čte paměť
Pokud proces provede kroky 2 a 3 pouze jednou pro každý bit načtených dat nebo data vypadnou z paměti kvůli tlaku paměti, mmap()
bude pomalejší.
read()
kroky:
- Systémové volání zkopíruje data z disku do mezipaměti stránky (může nebo nemusí chyba stránky, data již mohou být v mezipaměti stránky, což způsobuje přeskočení)
- Data zkopírovaná z mezipaměti stránky do paměti procesu (může, ale nemusí být chyba stránky)
Mapování paměti tento výkon překoná pouze díky této extra kopii z mezipaměti stránek do paměti zpracování. Ale pouhá kopie stránky paměti (nebo méně) musí být provedena několikrát, aby se překonaly náklady na nastavení mapování - pravděpodobně. Kolikrát závisí na vašem systému. Šířka pásma paměti, jak je celý váš systém využíván, všechno. Pokud by například čas, který spotřebovala správa paměti jádra k nastavení mapování, stejně nevyužil žádný jiný proces, náklady na vytvoření mapování skutečně nejsou příliš vysoké. Naopak, pokud máte ve svém systému velké množství zpracování, které zahrnuje mnoho vytváření/destrukce mapování virtuální paměti (tj. mnoho procesů s krátkou životností), může být dopad IO mapovaných do paměti významný.
Pak je tu read()
pomocí přímého IO:
- Systémové volání pro čtení z disku do prostoru paměti procesu. (může nebo nemusí způsobit chybu stránky)
Čtení s přímým vstupem a výstupem je téměř nemožné překonat z hlediska výkonu. Ale musíte skutečně vyladit své IO vzory podle hardwaru, abyste maximalizovali výkon.
Všimněte si, že proces může do značné míry kontrolovat, zda čtení dat způsobí chybu stránky ve vyrovnávací paměti, kterou proces používá ke čtení.
Je tedy přístup k souborům mapovaným v paměti rychlejší? Možná je, možná není.
Záleží na vašem vzoru (vzorech) přístupu. Spolu s vaším hardwarem a vším ostatním v cestě (cestách) IO.
Pokud streamujete 30GB video soubor na počítači se 4 GB RAM a nikdy se nevrátíte zpět a nepřečtete žádná data, mapování paměti je pravděpodobně nejhorší způsob, jak to číst.
Naopak, pokud máte 100 MB vyhledávací tabulku pro některá data, ke kterým při zpracování náhodně přistupujete miliardy a miliardkrát, a máte dostatek paměti, aby se soubor nikdy neodstránil, mapování paměti rozdrtí všechny ostatní přístupové metody.
Jedna obrovská výhoda souborů mapovaných v paměti
Soubory mapování paměti mají oproti jiným formám IO obrovskou výhodu:jednoduchost kódu. Je opravdu těžké překonat jednoduchost přístupu k souboru, jako by byl v paměti. A většinou není rozdíl ve výkonu mezi mapováním paměti souboru a prováděním diskrétních IO operací tak velký.