Prednosti i nedostaci HugePages

Prednosti i nedostaci HugePages

Prijevod članka pripremljen za studente kursa "Linux administrator".

Prethodno sam govorio o tome kako testirati i omogućiti korištenje Hugepages na Linuxu.
Ovaj članak će biti koristan samo ako zaista imate mjesto za korištenje Hugepages. Upoznao sam mnogo ljudi koji su prevareni izgledom da će Hugepages magično poboljšati produktivnost. Međutim, ogromanpaging je složena tema i može smanjiti performanse ako se koristi nepravilno.

Dio 1: Provjera da su ogromne stranice omogućene na Linuxu (originalno ovdje)

Problem:
Morate provjeriti da li je HugePages omogućen na vašem sistemu.

rješenje:
Prilično je jednostavno:

cat /sys/kernel/mm/transparent_hugepage/enabled

Dobićete nešto ovako:

always [madvise] never

Vidjet ćete listu dostupnih opcija (uvek, ludo, nikad), a trenutno aktivna opcija će biti zatvorena u zagradama (podrazumevano madvise).

madvise znači da transparent hugepages omogućeno samo za memorijska područja koja eksplicitno zahtijevaju korištenje ogromnih stranica madvise(2).

uvijek znači da transparent hugepages uvijek omogućen za sve procese. Ovo obično poboljšava performanse, ali ako imate slučaj upotrebe u kojem mnogi procesi troše malu količinu memorije, onda se ukupno opterećenje memorije može dramatično povećati.

nikada znači da transparent hugepages neće biti uključeno čak ni kada se to zatraži pomoću madvisea. Da saznate više, kontaktirajte dokumentaciju Linux kerneli.

Kako promijeniti zadanu vrijednost

Opcija 1: Direktno promijeniti sysfs (nakon ponovnog pokretanja parametar će se vratiti na svoju zadanu vrijednost):

echo always >/sys/kernel/mm/transparent_hugepage/enabled
echo madvise >/sys/kernel/mm/transparent_hugepage/enabled
echo never >/sys/kernel/mm/transparent_hugepage/enabled

Opcija 2: Promijenite zadanu vrijednost sistema ponovnim kompajliranjem kernela sa modificiranom konfiguracijom (ova opcija se preporučuje samo ako koristite prilagođeno jezgro):

  • Za postavljanje uvijek prema zadanim postavkama, koristite:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • Da postavite madvise kao zadanu, koristite:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

Dio 2: Prednosti i nedostaci HugePages

Pokušat ćemo selektivno objasniti prednosti, nedostatke i moguće zamke korištenja Hugepages. Budući da će tehnološki složen i pedantan članak vjerovatno biti težak za razumijevanje ljudima koji se zavaravaju misleći da je Hugepages lijek, žrtvovaću preciznost radi jednostavnosti. Vrijedi samo imati na umu da su mnoge teme zaista složene i stoga uvelike pojednostavljene.

Imajte na umu da govorimo o 64-bitnim x86 sistemima koji koriste Linux, i da jednostavno pretpostavljam da sistem podržava transparentne ogromne stranice (pošto nije nedostatak što se ogromne stranice ne prepisuju), kao što je slučaj u gotovo svakom modernom Linuxu okruženje.

Priložit ću više tehničkog opisa na linkovima ispod.

Virtuelna memorija

Ako ste C++ programer, znate da objekti u memoriji imaju specifične adrese (vrijednosti pokazivača).

Međutim, ove adrese ne odražavaju nužno fizičke adrese u memoriji (RAM adrese). Oni predstavljaju adrese u virtuelnoj memoriji. Procesor ima poseban MMU (memory management unit) modul koji pomaže kernelu da mapira virtuelnu memoriju na fizičku lokaciju.

Ovaj pristup ima mnogo prednosti, ali najvažnije su:

  • Performanse (iz raznih razloga);
  • Izolacija programa, odnosno nijedan program ne može čitati iz memorije drugog programa.

Šta su stranice?

Virtuelna memorija je podeljena na stranice. Svaka pojedinačna stranica ukazuje na određenu fizičku memoriju, može ukazivati ​​na područje u RAM-u ili može ukazivati ​​na adresu dodijeljenu fizičkom uređaju, kao što je video kartica.

Većina stranica s kojima se bavite ili usmjeravaju na RAM ili se zamjenjuju, što znači da su pohranjene na vašem tvrdom disku ili SSD-u. Kernel upravlja fizičkim izgledom svake stranice. Ako se pristupi lažnoj stranici, kernel zaustavlja nit koja pokušava pristupiti memoriji, čita stranicu sa tvrdog diska/SSD-a u RAM, a zatim nastavlja izvršavanje niti.

Ovaj proces je transparentan, što znači da se ne čita direktno sa HDD/SSD-a. Veličina normalnih stranica je 4096 bajtova. Veličina ogromnih stranica je 2 megabajta.

Translacijski asocijativni bafer (TLB)

Kada program pristupi stranici memorije, CPU mora znati sa koje fizičke stranice da čita podatke (to jest, ima virtuelnu mapu adresa).

Kernel ima strukturu podataka (tabelu stranica) koja sadrži sve informacije o stranicama koje se koriste. Koristeći ovu strukturu podataka, možete mapirati virtuelnu adresu u fizičku adresu.

Međutim, tabela stranica je prilično složena i spora, tako da jednostavno ne možemo analizirati cijelu strukturu podataka svaki put kada proces pristupi memoriji.

Srećom, naš procesor ima TLB koji kešira mapiranje između virtualnih i fizičkih adresa. To znači da iako trebamo raščlaniti tabelu stranica pri prvom pokušaju pristupa, svi sljedeći pristupi stranici mogu se rukovati u TLB-u, što omogućava brz rad.

Budući da je implementiran kao fizički uređaj (što ga čini brzim prije svega), njegov kapacitet je ograničen. Dakle, ako želite pristupiti više stranica, TLB neće moći pohraniti mapiranja za sve njih, što će uzrokovati da vaš program radi mnogo sporije.

Hugepages dolazi u pomoć

Dakle, šta možemo učiniti da izbjegnemo prelijevanje TLB-a? (Pretpostavljamo da je programu i dalje potrebna ista količina memorije).

Ovdje dolazi Hugepages. Umjesto 4096 bajtova koji zahtijevaju samo jedan TLB unos, jedan TLB unos sada može ukazivati ​​na ogromna 2 megabajta. Pretpostavimo da TLB ima 512 unosa, ovdje bez ogromnih stranica možemo upariti:

4096 b⋅512=2 MB

Kako onda da se poredimo sa njima:

2 MB⋅512=1 GB

Zbog toga je Hugepages sjajan. Oni mogu poboljšati produktivnost bez mnogo truda. Ali ovdje postoje značajna upozorenja.

Ogromne lažne stranice

Kernel automatski prati koliko često se koristi svaka memorijska stranica. Ako nema dovoljno fizičke memorije (RAM), kernel će premjestiti manje važne (rjeđe korištene) stranice na tvrdi disk kako bi oslobodio nešto RAM-a za važnije stranice.
U principu, isto se odnosi i na Hugepages. Međutim, kernel može mijenjati samo cijele stranice, a ne pojedinačne bajtove.

Recimo da imamo ovakav program:

char* mymemory = malloc(2*1024*1024); // Возьмем это за одну Hugepage!
// Заполним mymemory какими-либо данными
// Сделаем много других вещей,
// которые приведут к подмене страницы mymemory
// ...
// Запросим доступ только к первому байту
putchar(mymemory[0]); 

U ovom slučaju, kernel će morati zamijeniti (pročitati) čak 2 megabajta informacija sa tvrdog diska/SSD-a samo da biste mogli pročitati jedan bajt. Što se tiče običnih stranica, samo 4096 bajtova treba pročitati sa tvrdog diska/SSD-a.

Stoga, ako je ogromna stranica zamijenjena, čitanje je brže samo ako trebate pristupiti cijeloj stranici. To znači da ako pokušavate nasumično pristupiti različitim dijelovima memorije i čitate samo nekoliko kilobajta, trebali biste koristiti obične stranice i ne brinuti ni o čemu drugom.

S druge strane, ako trebate pristupiti velikom dijelu memorije uzastopno, ogromne stranice će poboljšati vaše performanse. Međutim, morate ga sami testirati (ne sa apstraktnim softverom) i vidjeti šta radi brže.

Dodjela u memoriji

Ako pišete C, znate da možete zahtijevati proizvoljno male (ili gotovo proizvoljno velike) količine memorije iz hrpe koristeći malloc(). Recimo da vam treba 30 bajtova memorije:

char* mymemory = malloc(30);

Programeru može izgledati da "zahtijevate" 30 bajtova memorije od operativnog sistema i vraćate pokazivač na neku virtuelnu memoriju. Ali zapravo malloc () je samo C funkcija koja poziva unutar funkcije brk i sbrk da zatražite ili oslobodite memoriju od operativnog sistema.

Međutim, traženje sve više memorije za svaku alokaciju je neefikasno; najvjerovatnije je neki memorijski segment već oslobođen (free()), i možemo ga ponovo koristiti. malloc() implementira prilično složene algoritme za ponovno korištenje oslobođene memorije.

U isto vrijeme, za vas se sve dešava neprimjetno, pa zašto bi vas to zabrinjavalo? Ali zato što je izazov free() ne znači to memorija se nužno odmah vraća u operativni sistem.

Postoji takva stvar kao što je fragmentacija memorije. U ekstremnim slučajevima, postoje segmenti hrpe u kojima se koristi samo nekoliko bajtova, dok je sve između oslobođeno (free()).

Imajte na umu da je fragmentacija memorije nevjerovatno složena tema, pa čak i manje promjene programa mogu imati značajan utjecaj. U većini slučajeva, programi neće uzrokovati značajnu fragmentaciju memorije, ali morate biti svjesni da ako postoji problem s fragmentacijom u nekom području hrpe, ogromne stranice mogu pogoršati situaciju.

Selektivno korištenje ogromnih stranica

Nakon što ste pročitali ovaj članak, utvrdili ste koji dijelovi vašeg programa mogu imati koristi od korištenja ogromnih stranica, a koji ne. Dakle, da li bi ogromne stranice uopće trebale biti omogućene?

Srećom možete koristiti madvise()kako bi se omogućilo ogromno stranice samo za ona memorijska područja gdje bi to bilo korisno.

Prvo, provjerite da li hugepages radi u madvise() modu koristeći uputstva na početku članka.

Zatim koristite madvise()da kaže kernelu gde tačno da koristi ogromne stranice.

#include <sys/mman.h>
// Аллоцируйте большое количество памяти, которую будете использовать
size_t size = 256*1024*1024;
char* mymemory = malloc(size);
// Просто включите hugepages…
madvise(mymemory, size, MADV_HUGEPAGE);
// … и задайте следующее
madvise(mymemory, size, MADV_HUGEPAGE | MADV_SEQUENTIAL)

Imajte na umu da je ova metoda samo savjet kernelu o tome kako upravljati memorijom. To ne znači da će kernel automatski koristiti ogromne stranice za datu memoriju.

Pogledajte dokumentaciju (manpage)madviseda saznate više o upravljanju memorijom i madvise(), ova tema ima nevjerovatno strmu krivulju učenja. Dakle, ako namjeravate postati stvarno dobri u tome, pripremite se za čitanje i testiranje nekoliko sedmica prije nego što očekujete bilo kakve pozitivne rezultate.

Šta čitati?

Imate pitanje? Pišite u komentarima!

izvor: www.habr.com

Dodajte komentar