Je použití mapování paměti pro IPC ve sdílené paměti požadavkem?

hlasů
0

Existuje několik projektů, které používají MappedByteBuffers vrácené Java FileChannel.map () jako způsob sdílení IPC sdílené paměti mezi JVM na stejném hostiteli (viz Kronika fronty, Aeron IPC atd.). Pokud mohu říci, tento api jen sedí na vrcholu mmap volání. Implementace jazyka Java však neumožňuje anonymní mapování bez zálohy.

Moje otázka je, že v Java (1.8) a Linux (3.10) jsou MappedByteBuffers skutečně nezbytné pro implementaci IPC ve sdílené paměti, nebo by jakýkoli přístup ke společnému souboru poskytoval stejnou funkcionalitu? (Tato otázka se netýká výkonových důsledků používání MappedByteBuffer či nikoliv.)

Zde je moje pochopení:

  1. Když Linux načte soubor z disku, zkopíruje jeho obsah na stránky v paměti. Tato oblast paměti se nazývá mezipaměť stránky. Pokud to mohu říci, dělá to bez ohledu na to, která metoda Java (FileInputStream.read (), RandomAccessFile.read (), FileChannel.read (), FileChannel.map ()) nebo nativní metoda se používá ke čtení souboru ( s "free" a sledováním hodnoty "cache").
  2. Pokud se jiný proces pokusí načíst stejný soubor (zatímco je stále v mezipaměti), jádro to detekuje a nemusí jej znovu načíst. Pokud se vyrovnávací paměť stránek zaplní, budou stránky vyklizeny - špinavé se zapisují zpět na disk. (Stránky se také zapisují zpět, pokud existuje explicitní vyprázdnění na disk a pravidelně s vláknem jádra).
  3. Mít (velký) soubor již v mezipaměti je významným zvýšením výkonu, mnohem více než rozdíly založené na metodách Java, které používáme k otevření / čtení tohoto souboru.
  4. Program AC, který volá systémové volání mmap, může provést ANONYMOUS mapování, které v podstatě přiděluje stránky v mezipaměti, které nejsou zálohovány skutečným souborem (takže není třeba vydávat skutečné zápisy na disk), ale Java se nezdá nabídnout to (bylo by mapování souboru v tmpfs stejné?)
  5. Pokud je soubor načten pomocí systémového volání mmap (C) nebo přes FileChannel.map () (Java), v zásadě se stránky souboru (v mezipaměti) načtou přímo do adresního prostoru procesu. Pomocí jiných metod k otevření souboru se soubor načte na stránky, které se nenacházejí v adresním prostoru procesu, a poté různé metody čtení a zápisu tohoto souboru kopírují některé bajty z / na tyto stránky do vyrovnávací paměti v adresovém prostoru procesu. . Tato kopie je zjevně výhodná z hlediska výkonu, ale moje otázka se netýká výkonu.

Stručně řečeno, pokud rozumím správně - zatímco mapování nabízí výhodu výkonu, nezdá se, že by nabídl jakoukoli funkci „sdílené paměti“, kterou již nedostáváme jen z povahy Linuxu a mezipaměti stránek.

Prosím, dejte mi vědět, kde je moje porozumění vypnuto.

Dík.

Položena 22/05/2020 v 21:20
zdroj uživatelem
V jiných jazycích...                            


2 odpovědí

hlasů
0

Za zmínku stojí tři body: výkon a souběžné změny a využití paměti.

Máte pravdu v hodnocení, že MMAP obvykle nabízí výhodu výkonu oproti IO založeným na souborech. Výhoda výkonu je zvláště důležitá, pokud kód provádí v malém bodě souboru spoustu malých IO.

zvažte změnu N-tého bajtu: s mmap buffer[N] = buffer[N] + 1 as přístupem založeným na souborech potřebujete (alespoň) 4 kontroly systémových volání:

   seek() + error check
   read() + error check
   update value
   seek() + error check
   write + error check

Je pravdou, že počet skutečných IO (na disk) je pravděpodobně stejný.

Druhý bod, který stojí za zmínku o souběžném přístupu. S IO založeným na souborech se musíte starat o potenciální souběžný přístup. Budete muset vydat explicitní uzamčení (před přečtením) a odemknout (po zápisu), abyste zabránili dvěma procesům pro nesprávný přístup k hodnotě současně. Díky sdílené paměti mohou atomové operace eliminovat potřebu dalšího zámku.

Třetím bodem je skutečné využití paměti. V případech, kdy je velikost sdílených objektů významná, může použití sdílené paměti umožnit přístup k datům velkému počtu procesů bez přidělení další paměti. Pokud systémy omezené pamětí nebo systémy, které potřebují poskytovat výkon v reálném čase, může to být jediný způsob, jak získat přístup k datům.

Odpovězeno 29/05/2020 v 10:35
zdroj uživatelem

hlasů
0

Moje otázka je, že v Java (1.8) a Linux (3.10) jsou MappedByteBuffers skutečně nezbytné pro implementaci IPC ve sdílené paměti, nebo by jakýkoli přístup ke společnému souboru poskytoval stejnou funkcionalitu?

Záleží na tom, proč chcete implementovat IPC sdílené paměti.

IPC můžete jasně implementovat bez sdílené paměti; např. přes zásuvky. Takže pokud to neděláte z důvodů výkonu, není nutné dělat IPC sdílené paměti vůbec!

Takže výkon musí být jádrem každé diskuse.

Přístup pomocí souborů přes rozhraní Java classic io nebo nio API neposkytuje funkčnost ani výkon sdílené paměti.

Hlavním rozdílem mezi běžným I / O nebo Socket I / O a IPC se sdílenou pamětí je to, že první vyžaduje, aby aplikace výslovně vytvořily read a write syscalls pro odesílání a přijímání zpráv. To znamená další syscalls a zahrnuje kopírování dat jádra. Kromě toho, pokud existuje více vláken, potřebujete buď samostatný "kanál" mezi každou dvojicí vláken, nebo něco pro multiplexování více "konverzací" přes sdílený kanál. Posledně jmenované může vést k tomu, že se sdílený kanál stane překážkou souběžnosti.

Tyto režijní náklady jsou ortogonální pro mezipaměť stránky Linux.

Naproti tomu s IPC implementovaným pomocí sdílené paměti neexistují žádné read a write syscalls a žádný další krok kopírování. Každý "kanál" může jednoduše použít samostatnou oblast mapované vyrovnávací paměti. Vlákno v jednom procesu zapisuje data do sdílené paměti a pro druhý proces je téměř okamžitě viditelné.

Výzva spočívá v tom, že procesy musí 1) synchronizovat a 2) implementovat bariéry paměti, aby bylo zajištěno, že čtenář nevidí zastaralá data. Ale oba mohou být implementovány bez syscalls.

Při umývání je IPC sdílené paměti používající soubory mapované na paměť >> je << rychlejší než použití konvenčních souborů nebo soketů, a proto to lidé dělají.


Také jste se implicitně zeptali, zda IPC sdílené paměti lze implementovat bez souborů mapovaných v paměti.

  • Praktickým způsobem by bylo vytvoření souboru mapovaného na paměť pro soubor, který žije v systému souborů pouze pro paměť; např. "tmpfs" v Linuxu.

    Technicky je to stále soubor mapovaný na paměť. Nevyvoláváte však režijní náklady na propláchnutí dat na disk a vyhnete se potenciálnímu bezpečnostnímu problému soukromých dat IPC končících na disku.

  • Teoreticky byste mohli implementovat sdílený segment mezi dvěma procesy následujícím postupem:

    • V nadřazeném procesu použijte k vytvoření segmentu mmap MAP_ANONYMOUS | MAP_SHARED .
    • Podřízené procesy vidlice. To nakonec skončí veškerým sdílením segmentu mezi sebou a nadřazeným procesem.

    Realizace tohoto procesu v procesu Java by však byla ... náročná. AFAIK, Java to nepodporuje.

Odkaz:

Odpovězeno 31/05/2020 v 06:17
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more