|
|
Před praktickým dílem v seriálu Za tajemstvím kompilace uvedu v tomto příspěvku některé základní informace o nakládání s pamětí.
Paměť procesu
Z pohledu procesu se paměť jeví jako indexované souvislé pole bytů. Tato adresace vůbec neodopovídá umístění ve fyzické paměti. Překlad adres provádí hardware automaticky podle speciálních tabulek, které nastavuje jádro operačního systému. Při “potížích” předá hardware řízení nastavené obsluze a jádro může situaci vhodně vyřešit. Linux tak může alokovat (”vytvořit”) paměť pro proces, ukončit proces při neoprávněné manipulaci s pamětí nebo překročení limitů, obnovit odswapovanou paměť… Tato problematika je složitější a hlavně platformově závislá; běžný nejaderný a nesystémový programátor se však o ni nemusí zajímat.
Při spuštění se inicializuje paměť podle sekcí spouštěného objektového souboru (např. elf). Hardware umožňuje nastavit ochranu určitých částí paměti, čehož se v Linuxu samozřejmě využívá a např. spustitelný kód a inicializované konstanty nechává chránit proti zápisu. Inicializovanou “prostorovou dispozici” paměti lze za běhu procesu měnit. Zavedení dynamické knihovny vysvětlím na praktickém případě v příštím díle seriálu. Každý proces má svojí vlastní paměť, ale za běhu lze speciálním systémovým voláním nechat část své paměti “ztotožnit” s částí paměti jiného procesu. Získaná sdílená paměť umožňuje mimo jiné vůbec nejrychlejší způsob komunikace mezi procesy.
Fork a clone
Nově vytvořený proces (funkcí fork) de facto sdílí paměť se svým rodičem. Avšak z hlediska obou procesů se situace jeví, že dětský (dceřiný) proces má vlastní paměťový prostor vzniklý klonováním obsahu paměti rodičovského procesu. Jak je to možné? Při vytvoření procesu se totiž nastaví ochrana paměti proti přepsání. V okamžiku, kdy se jeden z procesů pokusí paměť přepsat, nastane chyba a jádro příslušnou přepisovanou stránku pro oba procesy “oddělí”, čehož si ani jeden proces “nevšimne”. Tato optimalizační technika se označuje jako copy on write (COW). Provedení forkování procesu je velmi rychlé, protože není nutné hned duplikovat celý paměťový prostor. Často nový proces bezprostředně po svém spuštění nechá ve svém paměťovém prostoru spustit jiný soubor; tímto způsobem může proces nově spustit jiný program.
Systémovým voláním clone lze nechat části paměti nechat části paměti trvale sdílet s rodičem. Extrémní formou sdílení jsou vlákna, která sdílí prakticky celou svou paměť (liší se pochopitelně zásobníky). Pro vytvoření vlákna a provedení souvisejících nastavení je nutná asistence knihovny (praktický příklad uveden v druhém díle seriálu).
Výhody forku
Často začátečníci podceňují výhody forkování procesu, proto je nyní rozeberu. Výhodou proti novému spuštění je rychlost díky technice COW, výhodou proti vláknům je například vyhnutí se problémům se synchronizací.
V praxi obvykle proces v krátkém časovém intervalu pracuje jen s relativně málo stránkami paměti (má malý aktuální tzv. working set). Tento design je výkonnostně žádoucí, protože dnešní počítače obsahují velmi velmi málo velmi rychlé paměti (registry procesoru), málo rychlé paměti (různé cache procesory), mnoho pomalé paměti (RAM moduly). Celá paměť využívaná procesem se tak ani zdaleka nevejde do procesorové cache, navíc procesy se přepínají. Pokud program v krátké době vyžaduje velký working set, procesor nemůže efektivně využívat své cache paměti - working set se do nich nevejde - a běh programu se podstatně zpomaluje kvůli nutnosti číst/zapisovat do pomalé operační paměti. Navíc překlad adresy není levná operace a výsledky se cachují do translation lookaside buffer (TLB).
Při malém working setu proces samozřejmě generuje pomaleji požadavky na “vytváření” svého paměťového prostoru. Jádro tak může tuto činnost výhodně spojit s dalšími činnostmi (např. plánování úloh, provést odložené zpracování taskletu, periodické činnosti…). Při “pomalém oddělování” stránek se proto prakticky neplýtvá výpočetní výkonem na “jednoúčelové” kontext switche.
V praxi se často dokonce do značné části alokované paměti od forkování do ukončení procesu vůbec nezapisuje.
Štítky: Principy Linuxu, Seriál : Za tajemstvím kompilace
“výhodou proti vláknům je například vyhnutí se problémům se synchronizací”
Pokud mam vice procesu a sdilenou pamet, musim se o synchronizaci starat taky (pres semafory), navic ta sdilena pamet a semafory se vytvari o trochu sloziteji, nez mutexy v threadech…
re edois : Proces vzniklý forkem nemá s rodičem klasickou sdílenou pamět (”shared memory”), proto není třeba řešit synchronizaci. Fakticky však po forku sdílí stejnou paměť, ale díky “línému” kopírování paměti metodou COW jsou obsahy paměťových prostorů obou procesů naprosto nezávislé. Je to popsané v článku.
V případě, že rodičovský proces měl před forkováním nějakou “zvláštní” paměť (shm_open, mmap…), je situace složitější; nerad bych to rozebíral v úvodním článku.
Pokud mam vice procesu a sdilenou pamet, musim se o synchronizaci starat taky
Linux zblízka využívá WordPress MU a běží na Blog.zive.cz. Vytvořte si svůj vlastní blog
Sledování přes RSS: články
a komentáře
Partnerská sekce pro IT profesionály:
Microsoft TechNet/MSDN