Re: Pomalý přístup u fork-procesu k paměti alokované přes mmap

Zdeněk Janiš zdenek.janis na brajan.cz
Pondělí Prosinec 12 11:52:05 CET 2016


Děkuji, je to zajímavý poznatek...

Dne 9.12.2016 v 19:46 Pavel Kankovsky napsal(a):
> On Fri, 9 Dec 2016, Zdeněk Janiš wrote:
>
>> Alokuji pole přes mmap(), aby bylo možné s touto pamětí pracovat i ve
>> forknutých procesech.
>> A překvapil mě fakt, že funkce, která s tímto polem pracuje, je ve
>> forknutém procesu pomalejší než v hlavním procesu. Uniká mi důvod proč
>> to tak je...
>>
>> V příloze zasílám příklad, na kterém to je vidět. Na mém počítači je
>> rozdíl kolem 50ms. Zajímalo by mě zda se to stejně bude chovat i
>> jinde. Tak pokud budete mít chuť vyzkoušejte a podělte se o výsledky.
>
> Absolutní rozdíl není ani tak zajímavý jako relativní.
>
> Zkusil jsem to na třech různých strojích (různý hardware, různý počet
> CPU, různé verze Linuxu) a koukal jsem jak blázen, protože jsem ve všech
> případech dostal poměr blízký 2:1 v neprospěch forknutých procesů.
>
> Zkusil jsem, co se stane, když průchod pameti provedu v proc() desetkrát
> a výsledek byl docela překvapivý, protože v absolutních číslech zůstal
> rozdíl zhruba stejný a oba výsledky se spíš podobal desetinásobku té
> původní menší hodnoty.
>
> Je tedy zjevné, že se jedná o něco, co se ve forknutém procesu provádí
> jen při jediném průchodu.
>
> Na stroji, který má víc socketů, byly měly naměřené hodnoty největší
> rozptyl, což má podle mne na svědomí NUMA, protože variabilita se
> výrazně snížila, když jsem použil taskset, abych to připoutal k jednomu
> jádru.
>
> (Když jsem však nechal použít dvě jádra z téhož socketu, tak najednou
> některé forknuté případy byly stejné jako ten hlavní proces?! A tomu
> fakt nerozumím.)
>
> Schválně jsem zkusil spuštění proc() v hlavním procesu přesunout až na
> konec za všechny forky, ale výsledek to nezměnilo a forknuté procesy
> jsou o něco pomalejší. Smazat všechny rozdíly mezi procesy se mi povedlo
> tím, že jsem do zvláštního procesu přestěhoval i inicializaci, který
> byla původně v main().
>
> Celkově mi z toho plyne, že první přístup ke sdílené paměti (přesněji
> asi ke stránce této sdílené paměti) v určitém procesu je nějak
> penalizován a to i v případě, že proces je fork z jiného procesu, který
> už takový přístup provedl.
>
> Zkusil jsem do programu připsat, aby v proc() a začátku a po dokončení
> každého z 10 průchodů zavolal getrusage a vypsat ru_minflt. A je to
> jasné: první průchod v každém jednotlivém procesu udělá hromadu soft
> page faults.
> A pokud byla inicializace přímo v hlavním procesu, tak všechny page
> faulty nastaly tam a čtení už proběhlo hladce.
>
> Finta je nejspíš v tom, že fork() nekopíruje stránkové tabulky, protože
> by to v mnoha případech bylo zbytečné, zejména je-li použito tradiční
> kombo fork-execve, kdy je forknutý proces stejně téměř okamžitě nahrazen
> jiným programem.
>
>
>
> _______________________________________________
> Linux mailing list
> Linux na linux.cz
> http://www.linux.cz/mailman/listinfo/linux
>

-- 
   Zdeněk Janiš


Další informace o konferenci Linux