
Përkthimi i artikullit është përgatitur për studentët e kursit .
Më parë kam folur për mënyrën se si të kontrolloni dhe aktivizoni përdorimin e Hugepages në Linux.
Ky artikull do të jetë i dobishëm vetëm nëse keni një rast të vërtetë për të përdorur Hugepages. Kam takuar shumë njerëz që mashtrohen nga perspektiva se Hugepages do të rrisnin magjikisht performancën. Megjithatë, Hugepaging është një temë komplekse dhe nëse përdoret gabimisht, mund të ulë performancën.
Pjesa 1: kontrolloni nëse hugepages janë aktivizuar në Linux (origjinali) )
Problemi:
Duhet të kontrolloni nëse HugePages janë aktivizuar në sistemin tuaj.
Zgjidhja:
Ai është mjaft i thjeshtë:
cat /sys/kernel/mm/transparent_hugepage/enabledDo të merrni diçka të tillë:
always [madvise] neverDo të shihni një listë opsionesh të disponueshme (always, madvise, never), me opsionin aktual aktiv të rrethuar me kllapa (në mënyrë standarde madvise).
madvise do të thotë se transparent hugepages janë aktivizuar vetëm për zonat e memories që shprehimisht kërkojnë hugepages me anë të .
always do të thotë se transparent hugepages janë gjithmonë të aktivizuara dhe për të gjithë proceset. Zakonisht e rrit këtë performancën, por nëse keni një rast përdorimi ku shumë procese konsumojnë sasi të vogla memoriesh, ngarkesa e përgjithshme mbi memory-n mund të rritet ndjeshëm.
never do të thotë se transparent hugepages nuk do të aktivizohen as kur kërkohen me anë të madvise. Për më shumë informacion, konsultohuni me në thelb të Linux.
Si të ndryshoni vlerën e paracaktuar
Varianti 1: Ndryshoni drejtpërdrejt sysfs (pas rimbushjes, ai do të kthehet në vlerën e paracaktuar):
echo always >/sys/kernel/mm/transparent_hugepage/enabled
echo madvise >/sys/kernel/mm/transparent_hugepage/enabled
echo never >/sys/kernel/mm/transparent_hugepage/enabledVarianti 2: Ndryshoni vlerën sistemike të paracaktuar duke riprogramuar kernelin me një konfigurim të ndryshuar (ky opsion rekomandohet vetëm nëse po përdorni kernelin tuaj të personalizuar):
- Për të vendosur always si paracaktuar, përdorni:
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y # Komento CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y - Për të vendosur madvise si paracaktuar, përdorni:
CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y # Komento CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
Pjesa 2: Avantazhet dhe disavantazhet e HugePages
Do të përpiqemi të shpjegojmë përzgjedhshëm avantazhet, disavantazhet dhe gabimet e mundshme kur përdorim Hugepages. Duke qenë se është një artikull teknologjikisht i ndërlikuar dhe pedant, ndoshta do të jetë i vështirë për t'u kuptuar nga ata që mashtrohen duke menduar se Hugepages janë një panace. Thjesht është e rëndësishme të mbani mend se shumë tema janë me të vërtetë të komplikuara dhe prandaj janë tepër të thjeshtuara.
Kujdes, ne po flasim për sisteme 64-bit x86 që punojnë në Linux, dhe unë po supozoj se sistemi mbështet transparent hugepages (sepse nuk është një disavantazh që hugepages nuk zëvendësohen), siç ndodh praktikisht në çdo ambient modern Linux.
Në lidhjet më poshtë, do të vendos më shumë përshkrim teknik.
Memoria virtuale
Nëse jeni një programues C++, e dini se objektet në memori kanë adresa të caktuara (vlera treguese).
Megjithatë, këto adresa nuk pasqyrojnë domosdoshmërisht adresat fizike në memori (adresat në RAM). Ato përfaqësojnë adresat në memorin virtuale. Procesori ka një modul të veçantë MMU (njësia e menaxhimit të memories), e cila ndihmon kernelin të tregojë(memori virtuale) me vendndodhjen fizike.
Ky qasje ka shumë përparësi, por dy më të rëndësishmet janë:
- Performanca (për arsye të ndryshme);
- Izolimi i programeve, dmth asnjë nga programet nuk mund të lexojë nga memoria e një programi tjetër.
Çfarë janë faqet?
Memoria virtuale është e ndarë në faqe. Çdo faqe e veçantë tregon një memorie fizike të caktuar, ajo mund të tregojë një zonë në RAM, ose një adresë të caktuar për një pajisje fizike, siç është karta grafike.
Shumica e faqeve me të cilat punoni tregojnë ose në RAM, ose zëvendësohen (swap), dmth ruhen në hard disk ose SSD. Kernel menaxhon vendndodhjen fizike të çdo faqeje. Nëse një faqe e zëvendësuar akseshet, kernel ndalon rrjedhën që përpiqet të qasë në memori, lexon faqen nga hard disku/SSD në RAM, dhe më pas vazhdon ekzekutimin e rrjedhës.
Ky proces është transparent për rrjedhën, dmth nuk lexon domosdoshmërisht drejtpërdrejt nga hard disku/SSD. Madhësia e faqeve normale është 4096 byte. Madhësia e Hugepages është 2 megabyte.
Bufferi i asociativ i përkthimit (TLB)
Kur një program qaset në një faqe të caktuar të memories, procesori qendror duhet të dijë nga cila faqe fizike të lexojë të dhënat (dmth të ketë një hartë virtuale adresash).
Në kernel ekziston një strukturë të dhënash (tabela e faqeve), e cila përmban të gjithë informacionin mbi faqet që përdoren. Me këtë strukturë të dhënash, mund të tregoni adresën virtuale me adresën fizike.
Megjithatë, tabela e faqeve është mjaft e komplikuar dhe funksionon ngadalë, prandaj ne thjesht nuk mund ta analizojmë çdo herë të gjithë strukturën e të dhënave kur ndonjë proces akseson memorjen.
Fatmirësisht, në procesorin tonë ka një TLB që memorizon përputhjen ndërmjet adresave virtuale dhe fizike. Kjo do të thotë se, megjithëse na nevojitet të analizojmë tabelën e faqeve në përpjekjen e parë për të aksesuar, të gjitha kërkesat e mëpasme për faqen mund të përpunohen në TLB, duke siguruar një funksionim të shpejtë.
Duke qenë se ai është realizuar si një pajisje fizike (gjë që e bën atë kryesisht të shpejtë), kapaciteti i tij është i kufizuar. Prandaj, nëse dëshironi të aksesoni më shumë faqe, TLB nuk do të mund të ruajë përputhjen për të gjitha ato, si pasojë, programi juaj do të funksionojë shumë më ngadalë.
Hugepages vijnë për ndihmë.
Pra, çfarë mund të bëjmë për të shmangur mbushjen e TLB? (Supozojmë se programi ende ka nevojë për të njëjtën sasi memorjeje).
Këtu janë Hugepages. Në vend të 4096 biteve, të cilat kërkojnë vetëm një regjistrim në TLB, një regjistrim në TLB tani mund të tregojë për 2 megabajt. Le të supozojmë se TLB ka 512 regjistrime, këtu pa Hugepages mund të lidhim:
4096 b⋅512=2 MBNdërsa me to ne mund të lidhim:
2 MB⋅512=1 GBPikërisht për këtë Hugepages janë të mrekullueshme. Ata mund të përmirësojnë performancën pa ndonjë përpjekje të madhe. Por këtu ka disa rezervime të rëndësishme.
Zëvendësimi i Hugepages.
Nuk është procesi automatik që ndjek frekuencën e përdorimit të çdo faqeje të memorjes. Nëse memorie fizike (RAM) nuk është e mjaftueshme, bërthama do të zhvendosë faqet më pak të rëndësishme (ato që përdoren më rrallë) në diskun e fortë për të liruar një pjesë të RAM për faqet më të rëndësishme.
Në parim, e njëjta gjë vlen edhe për Hugepages. Megjithatë, bërthama mund të shkëmbejë vetëm faqe të plota, jo vetëm bite të veçanta.
Le të supozojmë se kemi një program të tillë:
char* mymemory = malloc(2*1024*1024); // Ta marrim këtë si një Hugepage!
// Të mbushim mymemory me ndonjë të dhënë
// Të bëjmë shumë gjëra të tjera,
// që do të rezultojnë në zëvendësimin e faqes mymemory
// ...
// Të kërkojmë akses vetëm në bitin e parë
putchar(mymemory[0]); Në këtë rast, bërthamës do t'i duhet të lexojë 2 megabajt informacioni nga disku të ngurtë/SSD vetëm për të lexuar një byte. Sa i përket faqeve të zakonshme, duhet të lexoni vetëm 4096 byte nga disku të ngurtë/SSD.
Prandaj, nëse hugepage zëvendësohet, leximi i tij ndodh më shpejt, vetëm nëse keni nevojë të aksesoni tërë faqen. Kjo do të thotë se nëse përpiqeni të aksesoni në mënyrë të rastësishme pjesë të ndryshme të memories dhe thjesht lexoni disa kilobajtë, duhet të përdorni faqet e zakonshme dhe të mos shqetësoheni për asgjë tjetër.
Nga ana tjetër, nëse keni nevojë të aksesoni një pjesë të madhe të memories në një mënyrë të vazhdueshme, hugepages do të rrisin performancën tuaj. Megjithatë, duhet ta kontrolloni vetë këtë (jo në rastin e një programi abstrakt) dhe të shikoni se çfarë do të punojë më shpejt.
Alokimi në memorie
Nëse po shkruani në C, e dini se mund të kërkoni sasi të vogla (apo pothuajse sasi të mëdha) memorjeje nga grumbulli me anë të malloc(). Supozojmë se keni nevojë për 30 byte memorie:
char* mymemory = malloc(30);Programuesit mund t'i duket se po “kërkoni” 30 byte memorie nga sistemi operativ dhe po kthejnë një tregues në disa memória virtuale. Por në të vërtetë malloc () është thjesht një funksion C që telefonon brenda funksioneve për të kërkuar ose çliruar memorjen nga sistemi operativ.
Megjithatë, kërkimi për më shumë dhe më shumë memorie për çdo alokim është e paefektshme; është shumë e mundshme që ndonjë segment memorie të jetë çliruar tashmë (free()), dhe ne mund ta përdorim përsëri atë. malloc() implementon algoritme mjaft të komplikuara për të ripërdorur memorjen e çliruar.
Në këtë rast, gjithçka ndodh pa e vënë re, pra pse duhet të shqetësoheni? Sepse thirrja free() nuk do të thotë që .
Ekziston një koncept i tillë si fragmentimi i memorjes. Në rastet ekstreme, ka segmente në grumbull, ku përdoren vetëm disa byte, ndërsa gjithçka që është midis tyre është çliruar. (free()).
Kujdesi, se fragmentimi i kujtesës është një temë jashtëzakonisht e ndërlikuar dhe edhe ndryshime të vogla në program mund të kenë një ndikim të madh në të. Në shumicën e rasteve, programet nuk shkaktojnë fragmentim të konsiderueshëm të kujtesës, por duhet të keni parasysh se nëse ka një problem me fragmentimin në ndonjë zonë të grumbujve, hugepages mund ta përkeqësojnë situatën.
Aplikimi selektiv i hugepages
Pasi keni lexuar artikullin, keni përcaktuar se cilat pjesë të programit tuaj mund të përfitojnë nga përdorimi i hugepages dhe cilat jo. A duhet ta aktivizoni fare hugepages?
Fatmirësisht, mund të përdorni madvise(), për të aktivizuar hugepaging vetëm për ato zona të kujtesës ku do të jetë e dobishme.
Së pari, kontrolloni që hugepages të punojnë në mënyrën madvise(), duke përdorur në fillim të artikullit.
Pastaj, përdorni madvise(), për t'i treguar bërthamës se ku saktësisht duhet të përdoren 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)Kujdes, kjo metodë është vetëm rekomandime për bërthamën mbi menaxhimin e kujtesës. Kjo nuk do të thotë se bërthama do të përdorë automatikisht hugepages për kujtesën e caktuar.
Shihni dokumentacionin , për të mësuar më shumë rreth menaxhimit të kujtesës dhe madvise(), kjo temë ka një kurbë jashtëzakonisht të madhe mësimi. Prandaj, nëse planifikoni të kuptoni vërtet atë, përgatituni të lexoni dhe testoni për disa javë përpara se të prisni ndonjë rezultat pozitiv.
Çfarë të lexoni?
Keni një pyetje? Shkruani në komentet!
Burimi: habr.com
