„HugePages“ privalumai ir trūkumai

„HugePages“ privalumai ir trūkumai

Kurso studentams parengto straipsnio vertimas "Linux administratorius".

Anksčiau kalbėjau apie tai, kaip išbandyti ir įgalinti „Hugepages“ naudojimą „Linux“.
Šis straipsnis bus naudingas tik tuo atveju, jei iš tikrųjų turite kur naudoti „Hugepages“. Sutikau daug žmonių, kuriuos suklaidino perspektyva, kad „Hugepages“ stebuklingai padidins produktyvumą. Tačiau didžiulis puslapių kūrimas yra sudėtinga tema ir gali pabloginti našumą, jei naudojamas netinkamai.

1 dalis: patikrinimas, ar didžiuliai puslapiai įjungti Linux sistemoje (originalas čia)

Problema:
Turite patikrinti, ar jūsų sistemoje įjungtas „HugePages“.

sprendimas:
Tai gana paprasta:

cat /sys/kernel/mm/transparent_hugepage/enabled

Jūs gausite kažką panašaus:

always [madvise] never

Pamatysite galimų parinkčių sąrašą (visada, madvise, niekada), o šiuo metu aktyvi parinktis bus pateikta skliausteliuose (pagal numatytuosius nustatymus beprotybė).

beprotybė reiškia kad transparent hugepages įjungta tik tose atminties srityse, kuriose aiškiai reikalaujama didžiulių puslapių madvise (2).

visada reiškia kad transparent hugepages visada įjungtas visiems procesams. Tai paprastai pagerina našumą, bet jei naudojate daug procesų, sunaudojančių nedidelį kiekį atminties, bendra atminties apkrova gali labai padidėti.

niekada reiškia kad transparent hugepages nebus įtrauktas net tada, kai bus prašoma naudojant madvise. Norėdami sužinoti daugiau, susisiekite dokumentacija Linux branduoliai.

Kaip pakeisti numatytąją reikšmę

Parinktis 1: Tiesiogiai pakeisti sysfs (po perkrovimo parametras grįš į numatytąją reikšmę):

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

Parinktis 2: pakeiskite sistemos numatytuosius nustatymus perkompiliuodami branduolį su pakeista konfigūracija (ši parinktis rekomenduojama tik jei naudojate pasirinktinį branduolį):

  • Jei norite nustatyti visada pagal numatytuosius nustatymus, naudokite:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • Norėdami nustatyti madvise kaip numatytąjį, naudokite:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

2 dalis: „HugePages“ privalumai ir trūkumai

Pabandysime pasirinktinai paaiškinti Hugepages naudojimo pranašumus, trūkumus ir galimas kliūtis. Kadangi technologiškai sudėtingas ir pedantiškas straipsnis tikriausiai bus sunkiai suprantamas žmonėms, kurie apsigauna manydami, kad „Hugepages“ yra panacėja, dėl paprastumo paaukosiu tikslumą. Tiesiog verta nepamiršti, kad daugelis temų yra tikrai sudėtingos ir todėl labai supaprastintos.

Atkreipkite dėmesį, kad mes kalbame apie 64 bitų x86 sistemas, kuriose veikia Linux, ir aš tiesiog darau prielaidą, kad sistema palaiko skaidrius didžiulius puslapius (nes tai nėra trūkumas, kad didžiuliai puslapiai nėra perrašomi), kaip yra beveik bet kuriame šiuolaikiniame Linux. aplinką.

Daugiau techninio aprašymo pridėsiu žemiau esančiose nuorodose.

Virtuali atmintis

Jei esate C++ programuotojas, žinote, kad atmintyje esantys objektai turi konkrečius adresus (rodiklio reikšmes).

Tačiau šie adresai nebūtinai atspindi fizinius adresus atmintyje (RAM adresus). Jie žymi adresus virtualioje atmintyje. Procesorius turi specialų MMU (atminties valdymo bloko) modulį, kuris padeda branduoliui susieti virtualiąją atmintį į fizinę vietą.

Šis metodas turi daug privalumų, tačiau svarbiausi yra šie:

  • Našumas (dėl įvairių priežasčių);
  • Programos izoliavimas, tai yra, jokia programa negali nuskaityti iš kitos programos atminties.

Kas yra puslapiai?

Virtualioji atmintis yra padalinta į puslapius. Kiekvienas atskiras puslapis nurodo konkrečią fizinę atmintį, gali nurodyti RAM sritį arba adresą, priskirtą fiziniam įrenginiui, pavyzdžiui, vaizdo plokštei.

Dauguma puslapių, su kuriais dirbate, nukreipia į RAM arba yra keičiami, tai reiškia, kad jie saugomi standžiajame diske arba SSD. Branduolys valdo fizinį kiekvieno puslapio išdėstymą. Jei pasiekiamas suklastotas puslapis, branduolys sustabdo giją, kuri bando pasiekti atmintį, nuskaito puslapį iš standžiojo disko / SSD į RAM ir toliau vykdo giją.

Šis procesas yra skaidrus, tai reiškia, kad jis nebūtinai nuskaitomas tiesiai iš HDD / SSD. Įprastų puslapių dydis yra 4096 baitai. Milžiniškų puslapių dydis yra 2 megabaitai.

Vertimo asociatyvinis buferis (TLB)

Kai programa pasiekia atminties puslapį, CPU turi žinoti, iš kurio fizinio puslapio nuskaityti duomenis (ty turėti virtualų adreso žemėlapį).

Branduolys turi duomenų struktūrą (puslapių lentelę), kurioje yra visa informacija apie naudojamus puslapius. Naudodami šią duomenų struktūrą galite susieti virtualų adresą su fiziniu adresu.

Tačiau puslapio lentelė yra gana sudėtinga ir lėta, todėl mes tiesiog negalime analizuoti visos duomenų struktūros kiekvieną kartą, kai procesas pasiekia atmintį.

Laimei, mūsų procesorius turi TLB, kuris talpykloje saugo virtualių ir fizinių adresų susiejimą. Tai reiškia, kad nors mes turime išanalizuoti puslapio lentelę pirmą kartą bandydami pasiekti puslapį, visos vėlesnės prieigos prie puslapio gali būti tvarkomos TLB, kad būtų galima greitai veikti.

Kadangi jis įdiegtas kaip fizinis įrenginys (dėl to jis visų pirma yra greitas), jo talpa yra ribota. Taigi, jei norite pasiekti daugiau puslapių, TLB negalės išsaugoti visų jų atvaizdų, todėl jūsų programa veiks daug lėčiau.

Milžiniški puslapiai ateina į pagalbą

Taigi, ką galime padaryti, kad išvengtume TLB perpildymo? (Manome, kad programai vis tiek reikia tiek pat atminties).

Čia pasirodo „Hugepages“. Vietoj 4096 baitų, kuriems reikia tik vieno TLB įrašo, vienas TLB įrašas dabar gali nurodyti didžiulius 2 megabaitus. Tarkime, kad TLB yra 512 įrašų, čia be didžiulių puslapių galime suderinti:

4096 b⋅512=2 MB

Tada kaip galime palyginti su jais:

2 MB⋅512=1 GB

Štai kodėl „Hugepages“ yra nuostabus. Jie gali pagerinti produktyvumą be didelių pastangų. Tačiau čia yra reikšmingų įspėjimų.

Didžiulių puslapių klastojimas

Branduolys automatiškai stebi, kaip dažnai naudojamas kiekvienas atminties puslapis. Jei nepakanka fizinės atminties (RAM), branduolys perkels mažiau svarbius (rečiau naudojamus) puslapius į standųjį diską, kad atlaisvintų šiek tiek RAM svarbesniems puslapiams.
Iš esmės tas pats galioja ir „Hugepages“. Tačiau branduolys gali apsikeisti tik visais puslapiais, o ne atskirais baitais.

Tarkime, kad turime tokią programą:

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

Tokiu atveju branduoliui reikės pakeisti (perskaityti) net 2 megabaitus informacijos iš standžiojo disko/SSD, kad galėtumėte nuskaityti vieną baitą. Kalbant apie įprastus puslapius, iš standžiojo disko / SSD reikia nuskaityti tik 4096 baitus.

Todėl, jei didžiulis puslapis yra nepaisomas, jis greičiau skaitomas tik tada, kai reikia pasiekti visą puslapį. Tai reiškia, kad jei bandote atsitiktinai pasiekti skirtingas atminties dalis ir skaitote tik keletą kilobaitų, turėtumėte naudoti įprastus puslapius ir nesijaudinti dėl nieko kito.

Kita vertus, jei jums reikia nuosekliai pasiekti didelę atminties dalį, didžiuliai puslapiai pagerins jūsų našumą. Tačiau reikia pačiam išbandyti (ne su abstrakčia programine įranga) ir pažiūrėti, kas veikia greičiau.

Paskirstymas atmintyje

Jei rašote C, žinote, kad galite paprašyti savavališkai mažų (arba beveik savavališkai didelių) atminties kiekių iš krūvos naudodami malloc(). Tarkime, kad jums reikia 30 baitų atminties:

char* mymemory = malloc(30);

Programuotojui gali pasirodyti, kad jūs „prašote“ 30 baitų atminties iš operacinės sistemos ir grąžinate žymeklį į virtualią atmintį. Bet iš tikrųjų malloc () yra tik C funkcija, kuri iškviečiama iš funkcijos brk ir sbrk prašyti arba atlaisvinti operacinės sistemos atminties.

Tačiau prašyti vis daugiau atminties kiekvienam paskirstymui yra neefektyvu; greičiausiai kai kurie atminties segmentai jau buvo atlaisvinti (free()), ir mes galime jį naudoti pakartotinai. malloc() įgyvendina gana sudėtingus algoritmus, skirtus pakartotinai panaudoti atlaisvintą atmintį.

Tuo pačiu jums viskas vyksta nepastebimai, tad kodėl tai turėtų jus jaudinti? Bet todėl, kad iššūkis free() to nereiškia atmintis būtinai nedelsiant grąžinama operacinei sistemai.

Yra toks dalykas kaip atminties suskaidymas. Ypatingais atvejais yra krūvos segmentų, kuriuose naudojami tik keli baitai, o viskas tarp jų buvo atlaisvinta (free()).

Atminkite, kad atminties suskaidymas yra nepaprastai sudėtinga tema ir net nedideli programos pakeitimai gali turėti didelės įtakos. Daugeliu atvejų programos nesukels didelio atminties suskaidymo, tačiau turėtumėte žinoti, kad jei kurioje nors krūvos srityje yra suskaidymo problema, dideli puslapiai gali pabloginti situaciją.

Atrankinis didžiulių puslapių naudojimas

Perskaitę šį straipsnį nustatėte, kurioms jūsų programos dalims gali būti naudinga naudoti didžiulius puslapius, o kurioms – ne. Taigi, ar didžiuliai puslapiai turėtų būti įjungti?

Laimei, galite naudoti madvise()įgalinti didžiulius puslapius tik tose atminties srityse, kur tai būtų naudinga.

Pirmiausia patikrinkite, ar didžiuliai puslapiai veikia madvise() režimu naudodami instrukcijos straipsnio pradžioje.

Tada naudokite madvise()kad branduoliui tiksliai nurodytų, kur naudoti didžiulius puslapius.

#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)

Atminkite, kad šis metodas yra tiesiog patarimas branduoliui, kaip valdyti atmintį. Tai nereiškia, kad branduolys automatiškai naudos didžiulius puslapius tam tikrai atminčiai.

Žiūrėkite dokumentaciją (manpage)madviseNorėdami sužinoti daugiau apie atminties valdymą ir madvise(), ši tema turi neįtikėtinai stačią mokymosi kreivę. Taigi, jei ketinate tai padaryti tikrai gerai, pasiruoškite skaityti ir išbandyti kelias savaites, kol tikėsitės teigiamų rezultatų.

Ką skaityti?

Turite klausimą? Rašyk komentaruose!

Šaltinis: www.habr.com

Добавить комментарий