
Raksts tulkots studentiem kursÄ .
IepriekÅ” es stÄstÄ«ju, kÄ pÄrbaudÄ«t un ieslÄgt Hugepages izmantoÅ”anu Linux.
Å is raksts bÅ«s noderÄ«gs tikai tad, ja jums tieÅ”Äm ir vieta, kur izmantot Hugepages. Esmu saskÄries ar daudz cilvÄku, kuri tiek maldinÄti ar perspektÄ«vu, ka Hugepages maÄ£iski palielinÄs veiktspÄju. TomÄr hugepaging ir sarežģīta tÄma, un nepareizi to izmantojot, tÄ var samazinÄt veiktspÄju.
1. daļa: pÄrbaudÄm, vai hugepages ir ieslÄgti Linux (oriÄ£inÄls )
ProblÄma:
JÄnoskaidro, vai jÅ«su sistÄmÄ ir ieslÄgti HugePages.
RisinÄjums:
Tas ir diezgan vienkÄrÅ”i:
cat /sys/kernel/mm/transparent_hugepage/enabledJÅ«s saÅemsiet kaut ko lÄ«dzÄ«gu Å”im:
always [madvise] neverJÅ«s redzÄsit pieejamo opciju sarakstu (always, madvise, never), un paÅ”laik aktÄ«vÄ opcija bÅ«s iekļauta iekavÄs (noklusÄjuma madvise).
madvise norÄda, ka transparent hugepages ir ieslÄgti tikai atmiÅas apgabalos, kuri skaidri pieprasÄ«juÅ”i hugepages, izmantojot .
always norÄda, ka transparent hugepages tiek vienmÄr ieslÄgti visiem procesiem. Parasti tas palielina veiktspÄju, bet ja jums ir lietojums, kur vairÄki procesi patÄrÄ nelielu daudzumu atmiÅas, kopÄjÄ atmiÅas slodze var strauji pieaugt.
never norÄda, ka transparent hugepages netiks ieslÄgti pat tad, ja tiek pieprasÄ«ti ar madvise. Lai uzzinÄtu vairÄk, skatieties Linux kodu.
KÄ mainÄ«t noklusÄjuma vÄrtÄ«bu
Varianta 1: TieÅ”i mainÄ«t sysfs (pÄc atsÄknÄÅ”anasparameters atgriezÄ«sies pie noklusÄjuma vÄrtÄ«bas):
echo always > /sys/kernel/mm/transparent_hugepage/enabled
echo madvise > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/enabledVarianta 2: Mainiet sistÄmas noklusÄjuma vÄrtÄ«bu, pÄrkompilÄjot kodu ar mainÄ«tu konfigurÄciju (Å”is variants ieteicams tikai tad, ja izmantojat savu kodu):
- Lai noklusÄjumÄ iestatÄ«tu always, izmantojiet:
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y # Ierakstiet CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y - Lai noklusÄjumÄ iestatÄ«tu madvise, izmantojiet:
CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y # Ierakstiet CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
2. daļa: HugePages priekŔrocības un trūkumi
MÄs mÄÄ£inÄsim izvÄlÄti izskaidrot Hugepages priekÅ”rocÄ«bas, trÅ«kumus un iespÄjamÄs kļūdas to izmantoÅ”anÄ. Å emot vÄrÄ, ka Å”is ir tehnoloÄ£iski sarežģīts un pedantisks raksts, tas, iespÄjams, bÅ«s grÅ«ti saprotams cilvÄkiem, kuri maldÄ«gi uzskata, ka Hugepages ir panaceja, es upurÄÅ”u precizitÄti vienkÄrŔības labad. JÄatceras, ka daudzas tÄmas ir patieÅ”Äm sarežģītas, un tÄpÄc tÄs tiek ievÄrojami vienkÄrÅ”otas.
LÅ«dzu, Åemiet vÄrÄ, ka mÄs runÄjam par 64 bitu x86 sistÄmÄm, kas darbojas uz Linux, un es vienkÄrÅ”i pieÅemu, ka sistÄma atbalsta transparent hugepages (jo tas, ka hugepages nav aizstÄjamas, nav trÅ«kums), kÄ tas notiek gandrÄ«z jebkurÄ mÅ«sdienu Linux vidÄ.
SaistÄ«tajÄs saitÄs zemÄk es pievienoÅ”u vairÄk tehniskÄs informÄcijas.
VirtuÄlÄ atmiÅa
Ja esat C++ programmÄtÄjs, jÅ«s zinÄt, ka objektiem atmiÅÄ ir konkrÄti adreses (pienÄcÄ«bas vÄrtÄ«bas).
TomÄr Ŕīs adreses obligÄti neatspoguļo fiziskÄs adreses atmiÅÄ (adreses RAM). TÄs ir adreses virtuÄlajÄ atmiÅÄ. Procesoram ir Ä«paÅ”s MMU (atmiÅas pÄrvaldÄ«bas vienÄ«ba) modulis, kas palÄ«dz kodolam saskaÅot virtuÄlo atmiÅu ar fizisko atraÅ”anÄs vietu.
Å Äds pieeja ir ar daudzÄm priekÅ”rocÄ«bÄm, bet vispÄrÄjÄs no tÄm ir:
- VeiktspÄja (dažÄdu iemeslu dÄļ);
- Programmu izolÄcija, tas ir, neviena programma nevar lasÄ«t citas programmas atmiÅu.
Kas ir lapas?
VirtuÄlÄ atmiÅa ir sadalÄ«ta lapÄs. Katrs atseviŔķs lapa norÄda uz konkrÄtu fizisko atmiÅu, tÄ var norÄdÄ«t uz jomu operatÄ«vajÄ atmiÅÄ, vai arÄ« uz adresi, ko pieŔķir fiziskais ierÄ«ce, piemÄram, videokarte.
LielÄkÄ daļa lapu, ar kurÄm jÅ«s saskaraties, norÄda vai nu uz RAM, vai ir aizvietotas (swap), tas ir, glabÄjas cietajÄ diskÄ vai SSD. Kodolaimi pÄrvalda katras lapas fizisko izvietojumu. Ja piekļūst aizvietotai lapai, kodols aptur pavedienu, kas mÄÄ£ina piekļūt atmiÅai, nolasot lapu no cietÄ diska/SSD uz operatÄ«vo atmiÅu un pÄc tam turpina pavediena izpildi.
Å is process ir caurspÄ«dÄ«gs pavedienam, tas ir, tas obligÄti nelasa tieÅ”i no cietÄ diska/SSD. NormÄlo lapu izmÄrs ir 4096 baiti. Hugepages izmÄrs ir 2 megabaiti.
SaistÄ«to pÄrvÄrÅ”anu buferis (TLB)
Kad programma piekļūst noteiktai atmiÅas lapai, centrÄlajam procesoram jÄzina, no kuras fiziskÄs lapas nolasÄ«t datus (t.i., jÄbÅ«t virtuÄlajai adresÄcijas kartei).
Kodola struktÅ«rÄ ir datu struktÅ«ra (lapu tabula), kas satur visu informÄciju par izmantotajÄm lapÄm. Ar Ŕīs datu struktÅ«ras palÄ«dzÄ«bu var pÄrvÄrst virtuÄlo adresi fiziskajÄ adresÄ.
TomÄr lapu tabula ir diezgan sarežģīta un darbojas lÄni, tÄpÄc mÄs nevaram katru reizi analizÄt visu datu struktÅ«ru, kad kÄds process piekļūst atmiÅai.
Par laimi, mÅ«su procesorÄ ir TLB, kas keÅ”Ä adresÄciju starp virtuÄlajÄm un fiziskajÄm adresÄm. Tas nozÄ«mÄ, ka, lai arÄ« mums ir jÄpÄrvÄrÅ” lapu tabula pie pirmÄ piekļūŔanas mÄÄ£inÄjuma, visi turpmÄkie piekļuves mÄÄ£inÄjumi var tikt apstrÄdÄti TLB, kas nodroÅ”ina ÄtrÄku darbÄ«bu.
KÄ tas ir ieviests kÄ fiziska ierÄ«ce (kas padara to primÄri Ätru), tÄ kapacitÄte ir ierobežota. TÄpÄc, ja vÄlaties piekļūt lielÄkam skaitam lapu, TLB nespÄs glabÄt kartÄÅ”anu visÄm tÄm, kÄ rezultÄtÄ jÅ«su programma strÄdÄs daudz lÄnÄk.
Hugepages nÄk palÄ«gÄ
TÄtad, ko mÄs varam darÄ«t, lai izvairÄ«tos no TLB pÄrpildīŔanas? (PieÅemam, ka programmai joprojÄm ir nepiecieÅ”ama tÄda pati atmiÅas jauda.)
Å eit parÄdÄs Hugepages. TÄ vietÄ, lai izmantotu 4096 baitus, kas prasa tikai vienu ierakstu TLB, viens ieraksts TLB tagad var norÄdÄ«t uz milzÄ«giem 2 megabaitiem. PieÅemsim, ka TLB ir 512 ierakstu, tad bez Hugepages mÄs varam kartÄt:
4096 bā
512=2 MBTad ar tiem mÄs varam kartÄt:
2 MBā
512=1 GBTÄpÄc Hugepages ir lieliska lieta. Tie var uzlabot veiktspÄju bez bÅ«tiskas piepÅ«les. Bet ir dažas bÅ«tiskas atrunas.
Hugepages apmaiÅa
Kodols automÄtiski seko katras atmiÅas lapas izmantoÅ”anas biežumam. Ja fiziskÄs atmiÅas (RAM) nepietiek, kodols pÄrvietos mazÄk svarÄ«gas (retÄk lietotas) lapas uz cieto disku, lai atbrÄ«votu daļu RAM svarÄ«gÄkÄm lapÄm.
PrincipÄ tas pats attiecas uz Hugepages. TomÄr kodols var apmainÄ«t tikai veselas lapas, nevis atseviŔķus baitus.
PieÅemot, ka mums ir Å”Äda programma:
char* mymemory = malloc(2*1024*1024);
// Å
emsim to par vienu Hugepage!
// AizpildÄ«sim mymemory ar kÄdiem datiem
// Veiksim daudz citu lietu,
// kas novedÄ«s pie mymemory lapu maiÅas
// ...
// Pieprasīsim piekļuvi tikai pirmajam baitam
putchar(mymemory[0]); Å ajÄ gadÄ«jumÄ kodolam bÅ«s jÄizlasa veseli 2 megabaiti informÄcijas no cietÄ diska/SSD tikai, lai jÅ«s varÄtu izlasÄ«t vienu baitu. AttiecÄ«bÄ uz parastÄm lapÄm no cietÄ diska/SSD jÄizlasa tikai 4096 baiti.
TÄpÄc, ja hugepage tiek nomainÄ«ts, tÄs lasīŔana notiek ÄtrÄk, tikai ja jums ir nepiecieÅ”ams piekļūt visai lapai. Tas nozÄ«mÄ, ka, ja jÅ«s mÄÄ£inÄt piekļūt nejauÅ”i dažÄdÄm atmiÅas daļÄm un vienkÄrÅ”i izlasÄt pÄris kilobaitus, jums vajadzÄtu izmantot parastas lapas un vairs par neko neuztraukties.
SavukÄrt, ja jums nepiecieÅ”ams piekļūt lielai atmiÅas daļai secÄ«gi, hugepages palielinÄs jÅ«su veiktspÄju. TomÄr jums paÅ”iem tas jÄiz pÄrbauda (nevis abstraktÄ vietnÄ) un jÄpÄrbauda, kas strÄdÄs ÄtrÄk.
AtmiÅas alokÄcija
Ja jÅ«s rakstÄt C valodÄ, jÅ«s zinÄt, ka varat pieprasÄ«t tik mazas (vai gandrÄ«z tik lielas) atmiÅas daļas no kaudzes, izmantojot malloc(). PieÅemsim, ka jums nepiecieÅ”ami 30 baiti atmiÅas:
char* mymemory = malloc(30);ProgrammÄtÄjam varÄtu Ŕķist, ka jÅ«s "pieprasÄt" 30 baitus atmiÅas no operÄtÄjsistÄmas un atgriežat rÄdÄ«tÄju uz kÄdu virtuÄlo atmiÅu. Bet patiesÄ«bÄ malloc () ir vienkÄrÅ”i C funkcija, kas iekÅ”Äji sauc funkcijas lai pieprasÄ«tu vai atbrÄ«votu atmiÅu no operÄtÄjsistÄmas.
TomÄr, pieprasÄ«t arvien vairÄk un vairÄk atmiÅas katrai alokÄcijai nav efektÄ«vi; visdrÄ«zÄk kÄds atmiÅas segments jau tika atbrÄ«vots (free()), un mÄs varam to atkÄrtoti izmantot. malloc() Ä«steno diezgan sarežģītus algoritmus, lai atkÄrtoti izmantotu atbrÄ«voto atmiÅu.
TajÄ paÅ”Ä laikÄ viss jums notiek nemanÄmi, tÄpÄc kÄpÄc tam bÅ«tu jÄpievÄrÅ” uzmanÄ«ba? TÄpÄc, ka izsaukums free() nenozÄ«mÄ, ka .
Ir pastÄv tÄds jÄdziens kÄ atmiÅas fragmentÄcija. EkstremÄlos gadÄ«jumos ir kaudzes segmenti, kur tiek izmantoti tikai daži baiti, kamÄr viss, kas atrodas starp tiem, ir atbrÄ«vots. (free()).
LÅ«dzu, Åemiet vÄrÄ, ka atmiÅas fragmentÄcija ir ÄrkÄrtÄ«gi sarežģīta tÄma, un pat nelielas izmaiÅas programmÄ var bÅ«t ievÄrojami ietekmÄt to. LielÄkajÄ daÄ¼Ä gadÄ«jumu programmas neizraisa nozÄ«mÄ«gu atmiÅas fragmentÄciju, taÄu jÄatceras, ka, ja ir raduÅ”Äs problÄmas ar fragmentÄciju kÄdÄ kaudzes apgabalÄ, hugepages var tikai pasliktinÄt situÄciju.
IzvÄles hugepages izmantoÅ”ana
PÄc raksta izlasīŔanas esat noteikuÅ”i, kÄdas jÅ«su programmas daļas var gÅ«t labumu no hugepages izmantoÅ”anas, un kÄdas ā nÄ. TÄtad, vai vispÄr bÅ«tu jÄieslÄdz hugepages?
Par laimi, jÅ«s varat izmantot madvise(), lai aktivizÄtu hugepaging tikai tÄm atmiÅas jomÄm, kur tas bÅ«s noderÄ«gi.
Vispirms pÄrliecinieties, ka hugepages darbojas madvise() režīmÄ, izmantojot raksta sÄkumÄ.
PÄc tam izmantojiet madvise(), lai norÄdÄ«tu kodolam, kur tieÅ”i izmantot 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)LÅ«dzu, Åemiet vÄrÄ, ka Ŕī metode ir tikai ieteikums kodolam par atmiÅas pÄrvaldÄ«bu. Tas nenozÄ«mÄ, ka kodols automÄtiski izmantos hugepages norÄdÄ«tajai atmiÅai.
LÅ«dzu, skatieties dokumentÄciju , lai uzzinÄtu vairÄk par atmiÅas pÄrvaldÄ«bu un madvise(), Å”ai tÄmai ir neticami stÄva mÄcÄ«bu lÄ«kne. TÄtad, ja jÅ«s patieÅ”Äm vÄlaties to izprast, gatavojieties lasÄ«t un testÄt vairÄkas nedÄļas, pirms cerat uz kaut kÄdu pozitÄ«vu rezultÄtu.
Ko lasīt?
Vai jums ir jautÄjums? Rakstiet komentÄros!
Avots: habr.com
