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ð prófa og virkja Hugepages á Linux.
Þessi grein mun aðeins vera gagnleg ef þú hefur í raun stað til að nota Hugepages. Ég hef hitt fullt af fólki sem lætur blekkjast af því að Hugepages muni auka framleiðni með töfrum. Hins vegar er risastórt efni flókið efni og getur dregið úr frammistöðu ef það er rangt notað.

Hluti 1: Staðfesta að risastórar síður séu virkar á Linux (upprunalega 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

Þú færð eitthvað svona:

always [madvise] never

Þú munt sjá lista yfir tiltæka valkosti (alltaf, madvise, aldrei), og valkosturinn sem nú er virkur verður innan sviga (sjálfgefið madvise).

madvise þýðir að transparent hugepages aðeins virkt fyrir minni svæði sem beinlínis biðja um risastórar síður sem nota madvise (2).

alltaf þýðir að transparent hugepages alltaf virkt fyrir alla ferla. Þetta bætir venjulega afköst, en ef þú ert með notkunartilvik þar sem mörg ferli neyta lítið magns af minni, þá getur heildarminnisálagið aukist verulega.

aldrei þýðir að transparent hugepages verður ekki innifalinn jafnvel þegar þess er óskað með madvise. Til að fá frekari upplýsingar, hafðu samband skjöl Linux kjarna.

Hvernig á að breyta sjálfgefnu gildi

Valkostur 1: Beint breyta sysfs (eftir endurræsingu mun færibreytan 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 2: Breyttu sjálfgefna kerfinu með því að setja saman kjarnann aftur með breyttri uppsetningu (þessi valkostur er aðeins mælt með ef þú ert að nota sérsniðna kjarna):

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

Part 2: Kostir og gallar HugePages

Við munum reyna að útskýra valkostlega kosti, galla og hugsanlega gildrur þess að nota Hugepages. Þar sem tæknilega flókin og vandræðaleg grein verður líklega erfitt að skilja fyrir fólk sem er blekkt til að halda að Hugepages sé töfralausn, mun ég fórna nákvæmni fyrir einfaldleikann. Það er rétt að hafa í huga að mörg viðfangsefnin eru mjög flókin og því mjög einfölduð.

Vinsamlegast athugaðu 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 ókostur að hugepages sé ekki skrifað yfir), eins og raunin er í næstum öllum nútíma Linux umhverfi.

Ég mun hengja frekari tæknilýsingu í tenglunum hér að neðan.

Sýndarminni

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

Hins vegar endurspegla þessi vistföng ekki endilega líkamleg heimilisföng í minni (RAM vistföng). Þeir tákna heimilisföng í sýndarminni. Örgjörvinn er með sérstaka MMU (memory management unit) einingu sem hjálpar kjarnanum að kortleggja sýndarminni á líkamlega staðsetningu.

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

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

Hvað eru síður?

Sýndarminni er skipt í síður. Hver einstök síða bendir á tiltekið líkamlegt minni, það getur bent á svæði í vinnsluminni eða það getur bent á heimilisfang sem er úthlutað líkamlegu tæki, eins og skjákorti.

Flestar síðurnar sem þú fjallar um benda annaðhvort á vinnsluminni eða er skipt út, sem þýðir að þær eru geymdar á harða disknum þínum eða SSD. Kjarninn stjórnar líkamlegu skipulagi hverrar síðu. Ef spoofed síða er opnuð stoppar kjarninn þráðinn sem er að reyna að komast inn í minnið, les síðuna af harða disknum/SSD inn í vinnsluminni og heldur síðan áfram að keyra þráðinn.

Þetta ferli er gagnsætt í straumi, sem þýðir að það les ekki endilega beint af HDD/SSD. Stærð venjulegra síðna er 4096 bæti. Hugepages stærð er 2 megabæti.

Translation-associative buffer (TLB)

Þegar forrit fer inn á minnissíðu verður örgjörvinn að vita hvaða efnissíðu á að lesa gögn af (þ.e. hafa sýndar heimilisfangskort).

Kjarninn hefur gagnaskipulag (síðutafla) sem inniheldur allar upplýsingar um þær síður sem verið er að nota. Með því að nota þessa gagnauppbyggingu geturðu kortlagt sýndarvistfang við líkamlegt heimilisfang.

Hins vegar er blaðsíðutaflan frekar flókin og hæg, þannig að við getum einfaldlega ekki greint alla gagnagerðina í hvert skipti sem ferli fer í minni.

Sem betur fer er örgjörvinn okkar með TLB sem vistar kortlagninguna á milli sýndar- og líkamlegs netfanga. Þetta þýðir að þó við þurfum að flokka blaðsíðutöfluna í fyrstu aðgangstilraun, er hægt að meðhöndla alla síðari aðgang að síðunni í TLB, sem gerir kleift að vinna hratt.

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

Hugepages kemur til bjargar

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

Þetta er þar sem Hugepages kemur inn. Í stað þess að 4096 bæti þurfi aðeins eina TLB færslu getur ein TLB færsla nú bent á heil 2 megabæti. Gerum ráð fyrir að TLB hafi 512 færslur, hér án Hugepages getum við jafnað:

4096 b⋅512=2 MB

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

2 MB⋅512=1 GB

Þetta er ástæðan fyrir því að Hugepages er frábært. Þeir geta bætt framleiðni án mikillar fyrirhafnar. En hér eru verulegir fyrirvarar.

Hugepages skopstæling

Kjarninn fylgist sjálfkrafa með hversu oft hver minnisíða er notuð. Ef það er ekki nóg líkamlegt minni (RAM), mun kjarninn flytja minna mikilvægar (sjaldnar notaðar) síður á harða diskinn til að losa um vinnsluminni fyrir mikilvægari síður.
Í grundvallaratriðum á það sama við um Hugepages. Hins vegar getur kjarninn aðeins skipt um heilar síður, ekki einstök bæti.

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

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

Í þessu tilviki þarf kjarninn að skipta út (lesa) allt að 2 megabæti af upplýsingum frá harða disknum/SSD bara til að þú getir lesið eitt bæti. Hvað venjulegar síður varðar þá þarf aðeins að lesa 4096 bæti af harða disknum/SSD.

Þess vegna, ef risastór síða er hnekkt, er það aðeins hraðari að lesa ef þú þarft að fá aðgang að allri síðunni. Þetta þýðir að ef þú ert að reyna að fá aðgang að mismunandi hlutum minnis af handahófi og ert bara að lesa nokkur kílóbæti, ættir þú að nota venjulegar síður og ekki hafa áhyggjur af neinu öðru.

Á hinn bóginn, ef þú þarft að fá aðgang að stórum hluta af minni í röð, munu risastórar síður bæta árangur þinn. Hins vegar þarftu að prófa það sjálfur (ekki með abstrakt hugbúnaði) og sjá hvað virkar hraðar.

Úthlutun í minningu

Ef þú skrifar C, veistu að þú getur beðið um geðþótta lítið (eða næstum geðþótta mikið) magn af minni úr haugnum með því að nota malloc(). Segjum að þú þurfir 30 bæti af minni:

char* mymemory = malloc(30);

Fyrir forritara kann að virðast að þú sért að „beiðja“ um 30 bæti af minni frá stýrikerfinu og skilar bendi í sýndarminni. En reyndar malloc () er bara C fall sem kallar innan fallsins brk og sbrk til að biðja um eða losa minni frá stýrikerfinu.

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

Á sama tíma gerist allt óséður fyrir þig, svo hvers vegna ætti það að hafa áhyggjur af þér? En vegna þess að áskorunin free() þýðir það ekki minni er endilega skilað strax í stýrikerfið.

Það er til eitthvað sem heitir minningabrot. Í öfgafullum tilfellum eru til hrúguhlutar þar sem aðeins nokkur bæti eru notuð á meðan allt þar á milli hefur verið losað (free()).

Vinsamlegast athugaðu að minnisbrot er ótrúlega flókið efni og jafnvel smávægilegar breytingar á forriti geta haft veruleg áhrif. Í flestum tilfellum munu forrit ekki valda verulegri sundrun minni, en þú ættir að vera meðvitaður um að ef það er vandamál með sundrun á einhverju svæði haugsins geta risastórar síður gert ástandið verra.

Sértæk notkun á risastórum síðum

Eftir að hafa lesið þessa grein hefurðu ákveðið hvaða hlutar forritsins þíns geta notið góðs af því að nota risastórar síður og hverjir ekki. Svo ætti yfirhöfuð að virkja risastórar síður?

Sem betur fer geturðu notað madvise()til að virkja risastóra söfnun aðeins fyrir þau minnissvæði þar sem það væri gagnlegt.

Athugaðu fyrst að hugepages sé í gangi í 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)

Athugaðu að þessi aðferð er einfaldlega ráð til kjarnans um hvernig eigi að stjórna minni. Þetta þýðir ekki að kjarninn muni sjálfkrafa nota risastórar síður fyrir tiltekið minni.

Vísað til skjala (manpage)madvisetil að læra meira um minnisstjórnun og madvise(), þetta efni hefur ótrúlega bratta námsferil. Svo ef þú ætlar að verða mjög góður í því skaltu búa þig undir að lesa og prófa í nokkrar vikur áður en þú býst við jákvæðum niðurstöðum.

Hvað á að lesa?

Ertu með spurningu? Skrifaðu í athugasemdir!

Heimild: www.habr.com

Bæta við athugasemd