GNU/Linux >> Znalost Linux >  >> Linux

mmap:bude mapovaný soubor okamžitě načten do paměti?

Ano, mmap vytváří mapování. Normálně nečte celý obsah čehokoli, co jste namapovali do paměti. Pokud to chcete udělat, můžete použít systémové volání mlock/mlockall, abyste přinutili jádro načíst do RAM obsah mapování, pokud je to možné.


Ne, ano, možná. Záleží.

Volání mmap obecně znamená pouze to, že do vaší aplikace je obsah mapovaného souboru mapován do jeho adresního prostoru jakoby tam byl soubor načten. Nebo, jako by soubor skutečně existoval v paměti, jako by byly jedno a totéž (což zahrnuje změny zapisované zpět na disk, za předpokladu, že máte přístup pro zápis).

Nic víc, nic míň. Nemá ponětí o načítání něčeho, ani aplikace neví, co to znamená.

Aplikace skutečně nezná nic takového, jako je paměť, ačkoliv systém virtuální paměti to tak dělá. Paměť, kterou může aplikace „vidět“ (a přistupovat k ní), může, ale nemusí odpovídat skutečné fyzické paměti, a to se může v zásadě kdykoli změnit, bez předchozího varování a bez zjevného důvodu (který je vaší aplikaci zřejmý).
Kromě možného malého zpoždění způsobeného chybou stránky si aplikace (v zásadě) vůbec neuvědomuje, že se něco takového děje, a má nad tím malou nebo žádnou kontrolu.

Aplikace obecně načtou stránky z mapovaných souborů (včetně hlavního spustitelného souboru!) na vyžádání v důsledku výskytu chyby. Operační systém se však obvykle pokusí spekulativně přednačíst data, aby optimalizoval výkon.

V praxi volání mmap okamžitě začne k (asynchronnímu) předběžnému načítání stránek od začátku mapování až do určité implementací specifikované velikosti. Což v zásadě znamená, že pro malé soubory by odpověď byla „ano“ a pro větší soubory by byla „ne“.
Nicméně mmap neblokuje čekání na dokončení načítání, což znamená, že nemáte žádnou záruku, že některý ze souborů bude v RAM bezprostředně po mmap vrátí (ne že byste měli takovou záruku kdykoli!). Dosud je odpověď „možná“.

Pod Linuxem, když jsem se naposledy díval, byla výchozí velikost předběžného načtení 31 bloků (~127 kB) - ale to se mohlo změnit, navíc je to laditelný parametr. Když se dotknete stránek blízko nebo na konci oblasti přednačítání, asynchronně se přednačítají další stránky.
Pokud jste naznačili MADV_RANDOMmadvise , přednačítání je "méně pravděpodobné", pod Linuxem toto přednačítání zcela zakáže.

Na druhou stranu zadáním MADV_SEQUENTIAL hint bude asynchronně přednačítat "agresivněji" počínaje začátkem mapování (a může rychleji zahodit přístupné stránky). Pod Linuxem „agresivněji“ znamená dvojnásobek běžného množství.

Dáváme MADV_WILLNEED hint naznačuje (ale nezaručuje), že všechny stránky v daném rozsahu budou načteny co nejdříve (protože říkáte, že k nim budete přistupovat). OS to může ignorovat, ale pod Linuxem se s tím zachází spíše jako s objednávkou než s nápovědou, a to až do maximálního RSS limitu procesu a limitu specifikovaného implementací (pokud si dobře pamatuji, 1/2 množství fyzické RAM ).
Všimněte si, že MADV_DONTNEED je pravděpodobně nesprávně implementován pod Linuxem. Nápověda není interpretována způsobem specifikovaným v POSIX, tj. jste v pořádku se stránkami, které jsou momentálně stránkovány, ale spíše tak, že chcete je zahodit . Což u stránek mapovaných pouze pro čtení nečiní žádný velký rozdíl (kromě malého zpoždění, o kterém jste řekl, že by bylo v pořádku), ale určitě to záleží pro všechno ostatní.
Konkrétně pomocí MADV_DONTNEED myslet si, že Linux uvolní nepotřebné stránky poté, co je OS líně zapsal na disk tak to nefunguje ! Musíte se explicitně synchronizovat nebo se připravit na překvapení.

Po zavolání readahead na deskriptoru souboru před voláním mmap (nebo po předchozím přečtení/zapsání souboru) se obsah souboru v praxi skutečně být okamžitě v RAM.
Toto je však pouze detail implementace (systém jednotné virtuální paměti) a podléhá tlaku paměti na systém.

Volání mlock - za předpokladu, že uspěje - okamžitě načte požadované stránky do paměti RAM. Blokuje se, dokud nejsou všechny stránky fyzicky přítomné, a máte záruku, že stránky zůstanou v paměti RAM, dokud je neodemknete.

Existuje funkce pro dotazování (mincore ) zda jsou některé nebo všechny stránky v určitém rozsahu aktuálně skutečně přítomny a funkce, které OS naznačují, co byste chtěli vidět, jak se děje bez jakýchkoli tvrdých záruk (madvise ) a konečně funkcionalitu, která vynutí přítomnost omezené podmnožiny stránek v paměti (mlock ) pro privilegované procesy.

Nemusí, jak kvůli nedostatku privilegií, tak kvůli překročení kvót nebo množství přítomné fyzické paměti RAM.


Ve výchozím nastavení mmap() pouze konfiguruje mapování a vrací (rychle).

Linux (alespoň) má možnost MAP_POPULATE (viz 'man mmap'), která dělá přesně to, čeho se týká vaše otázka.


Linux
  1. Vložení souboru do jiného souboru po prvním výskytu vzoru?

  2. Výstup do Stdout a zároveň Grep do souboru?

  3. Jaký je rozdíl mezi zápisem do souboru a namapovanou pamětí?

  1. Rekurzivní kat všechny soubory do jednoho souboru

  2. Uživatel není v souboru sudoers. Tento incident bude nahlášen

  3. Linux čtení swap zpět do paměti

  1. Jak uložit výstup SHOW PROCESSLIST do souboru v MySQL?

  2. Proč mají regiony mapované v paměti pouze pro čtení špinavé stránky?

  3. K čemu je mít část jádra ve virtuálním paměťovém prostoru linuxových procesů?