Prednosti i nedostaci HugePages

Prednosti i nedostaci HugePages

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

Ranije sam govorio o tome kako testirati i omogućiti Hugepages na Linuxu.
Ovaj će članak biti koristan samo ako stvarno imate mjesto za korištenje Hugepagesa. Upoznao sam mnogo ljudi koje je zavarala mogućnost da će Hugepages magično poboljšati produktivnost. Međutim, hugepaging je složena tema i može pogoršati performanse ako se neispravno koristi.

1. dio: Provjera jesu li hugepages omogućeni na Linuxu (izvorni здесь)

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

rješenje:
Prilično je jednostavno:

cat /sys/kernel/mm/transparent_hugepage/enabled

Dobit ćete nešto poput ovoga:

always [madvise] never

Vidjet ćete popis dostupnih opcija (uvijek, madvise, nikad), a trenutno aktivna opcija bit će u zagradama (prema zadanim postavkama madvise).

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

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

nikada znači da transparent hugepages neće biti uključen čak ni kada se to zatraži putem madvisea. Za više informacija kontaktirajte dokumentacija Linux kerneli.

Kako promijeniti zadanu vrijednost

Opcija 1: Izravna promjena sysfs (nakon ponovnog pokretanja parametar će se vratiti na 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 zadane postavke sustava ponovnim kompajliranjem kernela s izmijenjenom konfiguracijom (ova se opcija preporučuje samo ako koristite prilagođeni kernel):

  • Za postavljanje uvijek prema zadanim postavkama upotrijebite:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • Za postavljanje madvise kao zadanog, 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 Hugepagesa. Budući da će tehnološki složen i pedantan članak vjerojatno biti teško razumjeti ljudima koji se zavaravaju misleći da je Hugepages lijek za sve, žrtvovat ću točnost zbog jednostavnosti. Vrijedno je samo imati na umu da su mnoge teme zaista složene i stoga uvelike pojednostavljene.

Imajte na umu da govorimo o 64-bitnim x86 sustavima koji pokreću Linux i da jednostavno pretpostavljam da sustav podržava transparentne ogromne stranice (budući da nije nedostatak što se ogromne stranice ne prepisuju), kao što je slučaj u gotovo svakom modernom Linuxu okoliš.

Priložit ću više tehničkog opisa na poveznicama u nastavku.

Virtualna memorija

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

Međutim, te adrese ne odražavaju nužno fizičke adrese u memoriji (RAM adrese). Oni predstavljaju adrese u virtualnoj memoriji. Procesor ima poseban MMU (jedinica za upravljanje memorijom) modul koji pomaže kernelu mapirati virtualnu memoriju na fizičku lokaciju.

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

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

Što su stranice?

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

Većina stranica s kojima radite ili upućuju na RAM ili su zamijenjene, što znači da su pohranjene na vašem tvrdom disku ili SSD-u. Kernel upravlja fizičkim izgledom svake stranice. Ako se pristupi krivotvorenoj stranici, kernel zaustavlja nit koja pokušava pristupiti memoriji, čita stranicu s tvrdog diska/SSD-a u RAM, a zatim nastavlja izvršavati nit.

Ovaj proces je stream transparentan, što znači da ne čita nužno izravno s HDD/SSD-a. Veličina normalnih stranica je 4096 bajtova. Veličina velike stranice je 2 megabajta.

Prijevodno-asocijativni međuspremnik (TLB)

Kada program pristupi stranici memorije, CPU mora znati s koje fizičke stranice čitati podatke (to jest, imati mapu virtualne adrese).

Kernel ima strukturu podataka (tablica stranica) koja sadrži sve informacije o stranicama koje se koriste. Pomoću ove strukture podataka možete mapirati virtualnu adresu u fizičku adresu.

Međutim, tablica stranica prilično je 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 sprema preslikavanje između virtualnih i fizičkih adresa. To znači da iako trebamo analizirati tablicu stranica pri prvom pokušaju pristupa, svim sljedećim pristupima stranici može se upravljati u TLB-u, što omogućuje brz rad.

Budući da je implementiran kao fizički uređaj (što ga čini brzim na prvom mjestu), njegov kapacitet je ograničen. Dakle, ako želite pristupiti većem broju stranica, TLB neće moći pohraniti preslikavanja za sve njih, uzrokujući da vaš program radi puno sporije.

Hugepages dolazi u pomoć

Dakle, što možemo učiniti da izbjegnemo prekoračenje TLB-a? (Pretpostavljamo da program i dalje treba istu količinu memorije).

Tu na scenu stupa Hugepages. Umjesto 4096 bajtova koji zahtijevaju samo jedan TLB unos, jedan TLB unos sada može upućivati ​​na nevjerojatna 2 megabajta. Pretpostavimo da TLB ima 512 unosa, ovdje bez Hugepages možemo usporediti:

4096 b⋅512=2 MB

Kako se onda možemo uspoređivati ​​s njima:

2 MB⋅512=1 GB

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

Lažiranje ogromnih stranica

Kernel automatski prati koliko se često 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 vrijedi i za 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 trebati zamijeniti (pročitati) čak 2 megabajta informacija s tvrdog diska/SSD-a samo da biste vi pročitali jedan bajt. Što se tiče običnih stranica, samo 4096 bajtova treba pročitati s tvrdog diska/SSD-a.

Stoga, ako je hugepage nadjačana, č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 se ni o čemu drugom.

S druge strane, ako morate uzastopno pristupiti velikom dijelu memorije, hugepages će poboljšati vašu izvedbu. Međutim, morate sami testirati (ne s apstraktnim softverom) i vidjeti što radi brže.

Raspodjela u memoriji

Ako napiš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 se može činiti da "zahtijevate" 30 bajtova memorije od operativnog sustava i vraćate pokazivač na neku virtualnu memoriju. Ali zapravo malloc () je samo C funkcija koja poziva unutar funkcije brk i sbrk zatražiti ili osloboditi memoriju od operativnog sustava.

Međutim, zahtijevanje sve više i više memorije za svaku dodjelu je neučinkovito; najvjerojatnije je neki segment memorije već oslobođen (free()), i možemo ga ponovno upotrijebiti. malloc() implementira prilično složene algoritme za ponovno korištenje oslobođene memorije.

Pritom se za vas sve događa neprimjetno, pa zašto bi vas to trebalo brinuti? Ali zato izazov free() ne znači to memorija se nužno odmah vraća operativnom sustavu.

Postoji nešto poput fragmentacije pamćenja. U ekstremnim slučajevima, postoje segmenti hrpe gdje se koristi samo nekoliko bajtova, dok je sve između oslobođeno (free()).

Imajte na umu da je fragmentacija memorije nevjerojatno složena tema, pa čak i manje promjene u programu mogu imati značajan utjecaj. U većini slučajeva programi neće uzrokovati značajnu fragmentaciju memorije, ali trebali biste 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 čitanja ovog članka, utvrdili ste koji dijelovi vašeg programa mogu imati koristi od korištenja hugepages, a koji ne. Treba li uopće omogućiti hugepages?

Srećom možete koristiti madvise()omogućiti hugepaging samo za ona memorijska područja gdje bi to bilo korisno.

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

Zatim, koristite madvise()reći kernelu gdje točno treba koristiti hugepages.

#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 određenu memoriju.

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

Što čitati?

Imam pitanje? Pišite u komentarima!

Izvor: www.habr.com

Dodajte komentar