Kostir og gallar HugePages

Kostir og gallar HugePages

Þýðing á greininni unnin fyrir nemendur á námskeiðinu "Linux stjórnandi".

Áður talaði ég um hvernig á að athuga og virkja notkun Hugepages á Linux.
Þessi grein verður aðeins gagnleg ef þú hefur raunverulega notkunartilvik fyrir Hugepages. Ég hef rekist á marga sem láta blekkjast af loforði um að Hugepages muni auka afköst á töfra. Hins vegar er hugepageing flókið efni og ef það er notað rangt getur það í raun dregið úr afköstum.

1. hluti: Að athuga hvort hugepages séu virkjuð í Linux (upprunalega útgáfan) hér)

Vandamál:
Þú þarft að athuga hvort HugePages sé virkt á kerfinu þínu.

lausn:
Það er frekar einfalt:

cat /sys/kernel/mm/transparent_hugepage/enabled

Þú munt fá eitthvað svona:

always [madvise] never

Þú munt sjá lista yfir tiltæka valkosti (alltaf, brjálæðislega, aldrei), en virki valkosturinn verður innan sviga (sjálfgefið brjálæði).

brjálæði þýðir að transparent hugepages aðeins virkt fyrir minnissvæði sem biðja sérstaklega um risasíður með því að nota brjálæðislegt (2).

alltaf þýðir að transparent hugepages Virkt allan tímann og fyrir öll ferli. Þetta bætir venjulega afköst, en ef þú ert með notkunartilvik þar sem mörg ferli nota lítið magn af minni, getur heildarminnisálagið aukist verulega.

aldrei þýðir að transparent hugepages verður ekki innifalið jafnvel þótt óskað sé eftir því með madvise. Nánari upplýsingar er að finna á skjöl Linux kjarnar.

Hvernig á að breyta sjálfgefnu gildi

Valkostur 1: Breyta beint sysfs (eftir endurræsingu mun breytan fara aftur í sjálfgefið gildi):

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

Valkostur 2Breyttu sjálfgefnu kerfisstillingunum með því að endurþýða kjarnann með breyttri stillingu (þessi valkostur er aðeins ráðlagður ef þú ert að nota sérsniðinn kjarna):

  • Til að stilla alltaf sem sjálfgefið skaltu nota:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • Til að stilla madvise sem sjálfgefið gildi skaltu nota:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

2. hluti: Kostir og gallar HugePages

Við munum reyna að útskýra kosti, galla og hugsanlega gildrur þess að nota Hugepages á valkvæðan hátt. Þar sem tæknilega flókin og smámunaleg grein verður líklega erfið að skilja fyrir þá sem eru blekktir til að halda að Hugepages sé töfralausn, mun ég fórna nákvæmni fyrir einfaldleika. Það er vert að hafa í huga að mörg efni eru í raun flókin og því mjög einfölduð.

Athugið að við erum að tala um 64-bita x86 kerfi sem keyra Linux, og að ég geri einfaldlega ráð fyrir að kerfið styðji gegnsæjar hugepages (þar sem það er ekki galli að hugepages séu ekki skipt út), eins og er raunin í nánast öllum nútíma Linux umhverfum.

Ég mun setja inn nánari tæknilegar lýsingar í tenglana hér að neðan.

Sýndarminni

Ef þú ert C++ forritari, þá veistu að hlutir í minni hafa ákveðin vistföng (bendilgildi).

Þessi vistföng endurspegla þó ekki endilega vistföng raunminnis (RAM-vistföng). Þau tákna vistföng sýndarminnis. Örgjörvinn hefur sérstaka einingu, MMU (minnisstjórnunareining), sem hjálpar kjarnanum að tengja sýndarminni við raunlega staðsetningu.

Þessi aðferð hefur marga kosti, en þeir mikilvægustu eru:

  • Framleiðni (af ýmsum ástæðum);
  • Einangrun forrita, sem þýðir að ekkert forrit getur lesið úr minni annars forrits.

Hvað eru síður?

Sýndarminni er skipt í síður. Hver einstök síða vísar á ákveðinn stað í raunminninu, sem getur annað hvort verið staðsetning í vinnsluminni eða vistfang sem er úthlutað rauntæki, eins og skjákorti.

Flestar síðurnar sem þú hefur samskipti við vísa annað hvort í vinnsluminni eða eru skipt út, sem þýðir að þær eru geymdar á harða diski eða SSD diski. Kjarninn stýrir staðsetningu hverrar síðu. Ef aðgangur er að skiptu síðu stöðvar kjarninn þráðinn frá því að reyna að fá aðgang að minni, les síðuna af harða diskinum/SSD disknum í vinnsluminni og heldur síðan áfram keyrslu þráðarins.

Þetta ferli er þráðgegnsætt, sem þýðir að það les ekki endilega beint af harða diskinum/SSD diskinum. Venjulegar síður eru 4096 bæti að stærð. Risastórar síður eru 2 megabæti að stærð.

Þýðingarútlitsbuffer (TLB)

Þegar forrit opnar minnissíðu verður örgjörvinn að vita af hvaða efnislegri síðu á að lesa gögnin (þ.e.a.s. hann verður að hafa sýndarvistfangakort).

Kjarninn hefur gagnabyggingu (síðutöflu) sem inniheldur allar upplýsingar um síðurnar sem eru í notkun. Þessi gagnabygging gerir kleift að tengja sýndarvistfang við raunverulegt vistfang.

Hins vegar er síðutaflan nokkuð flókin og hæg, þannig að við getum einfaldlega ekki greint alla gagnabygginguna í hvert skipti sem ferli nálgast minni.

Sem betur fer er örgjörvinn okkar með TLB sem geymir vörpunina milli sýndar- og efnisvistfanga í skyndiminni. Þetta þýðir að þó að við þurfum að greina síðutöfluna fyrir fyrstu aðgangstilraunina, þá er hægt að vinna úr öllum síðari síðuopnunum í TLB, sem tryggir hraða virkni.

Þar sem það er útfært sem efnislegt tæki (sem gerir það hratt í fyrsta lagi) er afkastageta þess takmörkuð. Þess vegna, ef þú vilt fá aðgang að fleiri síðum, mun TLB ekki geta geymt vörpun fyrir þær allar, sem veldur því að forritið þitt keyrir mun hægar.

Hugepages kemur til bjargar

Hvað getum við þá gert til að forðast TLB yfirflæði? (Við gerum ráð fyrir að forritið þurfi enn sama magn af minni.)

Þetta er þar sem Hugepages koma inn í myndina. Í stað þess að 4096 bæti þurfi aðeins eina TLB færslu, getur ein TLB færsla nú bent á heil 2 megabæti. Miðað við TLB með 512 færslum, án Hugepages, getum við kortlagt:

4096 b⋅512=2 MB

Hvernig getum við þá borið þau saman við:

2 MB⋅512=1 GB

Þess vegna eru Hugepages svona flott. Þau geta aukið framleiðni án mikillar fyrirhafnar. En það eru nokkrir verulegir fyrirvarar.

Hugepages skipti

Kjarninn fylgist sjálfkrafa með því hversu oft hver minnissíða er notuð. Ef vinnsluminni (RAM) er ekki nóg mun kjarninn færa síður sem eru minna mikilvægar (sjaldnar notaðar) yfir á harða diskinn til að losa um vinnsluminni fyrir mikilvægari síður.
Í meginatriðum á það sama við um Hugepages. Kjarninn getur þó aðeins skipt um heilar síður, ekki einstök bæti.

Segjum sem svo að við höfum forrit eins og þetta:

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

Í þessu tilfelli þyrfti kjarninn að skipta (lesa) heilar 2 megabæti af upplýsingum af harða diskinum/SSD diskinum bara til þess að þú getir lesið einn bæti. Fyrir venjulegar síður þarf aðeins að lesa 4096 bæti af harða diskinum/SSD diskinum.

Þess vegna, ef hugepage er skipt út, er lestur hennar aðeins hraðari ef þú þarft að fá aðgang að allri síðunni. Þetta þýðir að ef þú ert að fá aðgang að mismunandi hlutum minnis af handahófi og lest aðeins nokkur kílóbæt, ættirðu að nota venjulegar síður og ekki hafa áhyggjur af neinu öðru.

Hins vegar, ef þú þarft að fá aðgang að stórum hluta af minni í röð, þá mun hugepages bæta afköstin. Hins vegar þarftu að prófa þetta sjálfur (ekki með óhlutbundnum hugbúnaði) og sjá hvor virkar hraðar.

Minnisúthlutun

Ef þú skrifar C, þá veistu að þú getur beðið um handahófskenndan lítinn (eða næstum handahófskenndan) minnisfjölda úr hrúgunni með því að nota malloc()Segjum að þú þurfir 30 bæti af minni:

char* mymemory = malloc(30);

Fyrir forritara gæti það virst eins og þú sért að „biðja um“ 30 bæti af minni frá stýrikerfinu og skila bendli til einhvers sýndarminni. En í raun og veru, malloc () — er bara C-fall sem kallar á föll innan frá brk og sbrk að biðja um eða losa minni úr stýrikerfinu.

Hins vegar er óhagkvæmt að biðja um meira og meira minni fyrir hverja úthlutun; líklegast hefur einhver minnishluti þegar losnað. (free()), og við getum endurnýtt það. malloc() útfærir frekar flóknar reiknirit til að endurnýta losað minni.

Og samt gerist þetta allt óséður fyrir þig, svo hvers vegna ætti það að angra þig? Vegna þess að áskorunin free() þýðir ekki að Minnið er alltaf skilað strax til stýrikerfisins.

Það er til hugtak sem kallast minnisbrotnun. Í öfgafullum tilfellum eru til hrúguhlutar þar sem aðeins fáeinir bæti eru notaðir en allt þar á milli hefur losnað. (free()).

Vinsamlegast athugið að minnisbrotnun er ótrúlega flókið efni og jafnvel minniháttar breytingar á forriti geta haft veruleg áhrif á það. Í flestum tilfellum valda forrit ekki verulegri minnisbrotnun, en það er mikilvægt að hafa í huga að ef brotnun er vandamál á ákveðnu svæði í hrúgunni geta hugepages aðeins gert illt verra.

Valkvæð notkun á risasíðum

Eftir að hafa lesið þessa grein hefur þú ákveðið hvaða hlutar forritsins þíns geta notið góðs af hugepages og hverjir ekki. Ættirðu þá að virkja hugepages yfirhöfuð?

Sem betur fer er hægt að nota madvise()að virkja hugepaging aðeins fyrir þau minnissvæði þar sem það nýtist.

Fyrst skaltu athuga hvort hugepages keyri í madvise() ham með því að nota leiðbeiningar í upphafi greinarinnar.

Notaðu síðan madvise()til að segja kjarnanum nákvæmlega hvar á að nota 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)

Vinsamlegast athugið að þessi aðferð er einfaldlega tilmæli um minnisstjórnun fyrir kjarnann. Það þýðir ekki að kjarninn muni sjálfkrafa nota hugepages fyrir tiltekið minni.

Vinsamlegast vísið til skjölunar (manpage) madvisetil að læra meira um minnisstjórnun og madvise()Þetta efni hefur ótrúlega brattan námsferil. Svo ef þú vilt virkilega ná tökum á því, þá skaltu búa þig undir að lesa og prófa í nokkrar vikur áður en þú væntir jákvæðra niðurstaðna.

Hvað á að lesa?

Hefurðu spurningu? Skrifaðu athugasemd!

Heimild: www.habr.com

Bæta við athugasemd