Virdeeler an Nodeeler vun HugePages

Virdeeler an Nodeeler vun HugePages

Iwwersetzung vum Artikel virbereet fir Course Studenten "Linux Administrator".

Virdrun hunn ech geschwat wéi ech Hugepages op Linux testen an aktivéieren.
Dësen Artikel wäert nëmme nëtzlech sinn wann Dir tatsächlech eng Plaz hutt fir Hugepages ze benotzen. Ech hu vill Leit begéint, déi duerch d'Perspektiv täuscht sinn datt Hugepages d'Produktivitéit magesch verbesseren. Wéi och ëmmer, Hugepaging ass e komplext Thema a kann d'Performance degradéieren wann se falsch benotzt ginn.

Deel 1: Verifizéieren datt Hugepages op Linux aktivéiert sinn (Original hei)

Problem:
Dir musst kontrolléieren ob HugePages op Ärem System aktivéiert ass.

Léisung:
Et ass relativ einfach:

cat /sys/kernel/mm/transparent_hugepage/enabled

Dir kritt esou eppes:

always [madvise] never

Dir gesitt eng Lëscht vun verfügbaren Optiounen (ëmmer, madvise, ni), an déi aktuell aktiv Optioun gëtt an Klammeren zougemaach (par défaut madvise).

madvise heescht dat transparent hugepages aktivéiert nëmme fir Erënnerungsberäicher déi explizit enorm Säiten benotzen madvis (2).

ëmmer heescht dat transparent hugepages ëmmer aktivéiert fir all Prozesser. Dëst verbessert normalerweis d'Performance, awer wann Dir e Gebrauchsfall hutt wou vill Prozesser eng kleng Quantitéit un Erënnerung verbrauchen, da kann d'Gesamt Erënnerungslaascht dramatesch eropgoen.

ni heescht dat transparent hugepages wäert net abegraff ginn och wann gefrot mat madvise. Fir méi gewuer ze ginn, kontaktéiert Dokumentatioun Linux Kärelen.

Wéi de Standardwäert z'änneren

Option 1: Direkt änneren sysfs (nom Neistart gëtt de Parameter op säin Defaultwäert zréck):

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

Option 2: Ännert de System Standard andeems Dir de Kernel mat enger geännerter Konfiguratioun nei kompiléiert (dës Optioun ass nëmme recommandéiert wann Dir e personaliséierte Kernel benotzt):

  • Fir ëmmer als Standard ze setzen, benotzt:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • Fir Madvise als Standard ze setzen, benotzt:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

Deel 2: Virdeeler an Nodeeler vun HugePages

Mir probéieren selektiv d'Virdeeler, Nodeeler a méiglech Falen vun der Benotzung vun Hugepages z'erklären. Zënter en technologesch komplexen a pedanteschen Artikel wäert méiglecherweis schwéier ze verstoen sinn fir Leit déi täuscht sinn ze denken datt Hugepages eng Panacea ass, wäert ech Genauegkeet fir Simplicitéit opferen. Et ass derwäert ze behalen datt vill vun den Themen wierklech komplex sinn an dofir immens vereinfacht.

Notéiert w.e.g. datt mir iwwer 64-Bit x86 Systemer schwätzen déi Linux lafen, an datt ech einfach dovun ausgoen datt de System transparent Hugepages ënnerstëtzt (well et keen Nodeel ass datt Hugepages net iwwerschriwwe ginn), wéi dat de Fall ass a bal all modernen Linux Ëmwelt.

Ech wäert méi technesch Beschreiwung an de Linken hei drënner befestegt.

Virtuell Gedächtnis

Wann Dir e C++ Programméierer sidd, wësst Dir datt Objeten an der Erënnerung spezifesch Adressen hunn (Zeigerwäerter).

Wéi och ëmmer, dës Adressen reflektéieren net onbedéngt kierperlech Adressen an der Erënnerung (RAM Adressen). Si representéieren Adressen an der virtueller Erënnerung. De Prozessor huet e spezielle MMU (Memory Management Unit) Modul deen de Kernel hëlleft virtuell Erënnerung op eng kierperlech Plaz ze mapen.

Dës Approche huet vill Virdeeler, awer déi wichtegst sinn:

  • Leeschtung (aus verschiddene Grënn);
  • Programm Isolatioun, dat ass, kee Programm kann aus der Erënnerung vun engem anere Programm liesen.

Wat sinn Säiten?

Virtuell Erënnerung ass a Säiten opgedeelt. All eenzel Säit weist op eng spezifesch kierperlech Erënnerung, et kann op e Gebitt am RAM weisen, oder et kann op eng Adress weisen, déi un engem kierperlechen Apparat zougewisen ass, wéi eng Videokaart.

Déi meescht vun de Säiten, mat deenen Dir handelt, weisen entweder op RAM oder gi gewiesselt, dat heescht datt se op Ärer Festplack oder SSD gespäichert sinn. De Kernel geréiert de kierperleche Layout vun all Säit. Wann eng spoofed Säit zougänglech ass, stoppt de Kärel de Fuedem deen probéiert op d'Erënnerung ze kommen, liest d'Säit vun der Festplack / SSD an de RAM, a fiert dann de Fuedem aus.

Dëse Prozess ass streamtransparent, dat heescht datt et net onbedéngt direkt vun der HDD / SSD gelies gëtt. D'Gréisst vun normale Säiten ass 4096 Bytes. Hugepages Gréisst ass 2 Megabytes.

Iwwersetzungsassociativ Puffer (TLB)

Wann e Programm Zougang zu enger Säit vun Erënnerung, der CPU muss wëssen, déi kierperlech Säit vun Daten liesen (dat ass, hunn eng virtuell Adress Kaart).

De Kernel huet eng Datestruktur (Säittabell) déi all Informatioun iwwer d'Säiten enthält déi benotzt gëtt. Mat dëser Datestruktur kënnt Dir eng virtuell Adress op eng kierperlech Adress mapen.

Wéi och ëmmer, d'Säittabell ass zimmlech komplex a lues, sou datt mir einfach d'ganz Datestruktur net analyséiere kënnen all Kéier wann e Prozess op d'Erënnerung kënnt.

Glécklecherweis huet eise Prozessor en TLB deen d'Mapping tëscht virtuellen a kierperlechen Adressen cacheiert. Dëst bedeit datt obwuel mir d'Säittabelle beim éischten Zougangsversuch musse parséieren, kënnen all spéider Zougrëff op d'Säit am TLB gehandhabt ginn, wat eng séier Operatioun erlaabt.

Well et als kierperlecht Apparat implementéiert gëtt (wat et iwwerhaapt séier mécht), ass seng Kapazitéit limitéiert. Also wann Dir op méi Säiten Zougang wëllt, wäert den TLB net fäeg sinn d'Mappings fir all vun hinnen ze späicheren, sou datt Äre Programm vill méi lues leeft.

Hugepages kënnt zur Rettung

Also wat kënne mir maachen fir TLB Iwwerschwemmung ze vermeiden? (Mir huelen un datt de Programm nach ëmmer déiselwecht Quantitéit un Erënnerung brauch).

Dëst ass wou Hugepages erakënnt. Amplaz vu 4096 Bytes, déi just eng TLB-Entrée erfuerderen, kann een TLB-Entrée elo op eng ganz 2 Megabytes weisen. Loosst eis unhuelen datt den TLB 512 Entréen huet, hei ouni Hugepages kënne mir passen:

4096 b⋅512=2 MB

Da wéi kënne mir mat hinnen vergläichen:

2 MB⋅512=1 GB

Dofir ass Hugepages genial. Si kënnen d'Produktivitéit verbesseren ouni vill Effort. Awer et gi bedeitend Viraussetzungen hei.

Hugepages Spoofing

De Kernel iwwerwaacht automatesch wéi dacks all Erënnerungssäit benotzt gëtt. Wann et net genuch kierperlecht Gedächtnis (RAM) gëtt, wäert de Kärel manner wichteg (manner dacks benotzt) Säiten op d'Harddisk réckelen fir e puer RAM fir méi wichteg Säiten ze befreien.
Am Prinzip gëllt dat selwecht fir Hugepages. Wéi och ëmmer, de Kernel kann nëmme ganz Säiten austauschen, net eenzel Bytes.

Loosst eis soen, mir hunn e Programm wéi dëst:

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

An dësem Fall muss de Kernel sou vill wéi 2 Megabytes vun Informatioun vun der Festplack / SSD ersetzen (liesen) just fir datt Dir ee Byte liest. Wat regelméisseg Säiten ugeet, musse just 4096 Bytes vun der Festplack/SSD gelies ginn.

Dofir, wann enorm Säit iwwerschratt ass, ass et nëmme méi séier ze liesen wann Dir op déi ganz Säit Zougang muss. Dëst bedeit datt wann Dir versicht zoufälleg op verschidden Deeler vun der Erënnerung ze kommen a just e puer Kilobytes liest, sollt Dir regelméisseg Säiten benotzen an Iech keng Suergen iwwer soss eppes maachen.

Op der anerer Säit, wann Dir sequenziell Zougang zu engem groussen Deel vun der Erënnerung braucht, wäerten enorm Säiten Är Leeschtung verbesseren. Wéi och ëmmer, Dir musst et selwer testen (net mat abstrakter Software) a kucke wat méi séier funktionnéiert.

Allocatioun an Erënnerung

Wann Dir C schreift, wësst Dir datt Dir arbiträr kleng (oder bal arbiträr grouss) Quantitéiten un Erënnerung aus dem Koup benotze kënnt malloc(). Loosst eis soen datt Dir 30 Bytes Erënnerung braucht:

char* mymemory = malloc(30);

Fir e Programméierer kann et schéngen datt Dir 30 Bytes Erënnerung vum Betribssystem "ufrot" an e Pointer op eng virtuell Erënnerung zréckginn. Awer eigentlech malloc () ass just eng C Funktioun déi vu bannent der Funktioun urufft brk an sbr Erënnerung vum Betribssystem ze froen oder ze befreien.

Wéi och ëmmer, méi a méi Erënnerung fir all Allokatioun ze froen ass ineffizient; et ass héchstwahrscheinlech datt e puer Erënnerungssegment scho befreit gouf (free()), a mir kënnen et weiderbenotzen. malloc() implementéiert zimmlech komplex Algorithmen fir befreit Erënnerung ze benotzen.

Zur selwechter Zäit geschitt alles fir Iech onnotéiert, also firwat sollt et Iech Suergen maachen? Mä well d'Erausfuerderung free() heescht dat net Erënnerung ass onbedéngt direkt an de Betribssystem zréck.

Et gëtt sou eppes wéi Erënnerungsfragmentatioun. An extremen Fäll ginn et Heap-Segmenter wou nëmmen e puer Bytes benotzt ginn, während alles dertëschend befreit ass (free()).

Notéiert w.e.g. datt d'Erënnerungsfragmentéierung en onheemlech komplext Thema ass, a souguer kleng Ännerungen un engem Programm kënnen e wesentlechen Impakt hunn. An de meeschte Fäll verursaache Programmer keng bedeitend Erënnerungsfragmentéierung, awer Dir sollt bewosst sinn datt wann et e Problem mat der Fragmentatioun an e puer Beräicher vum Koup ass, enorm Säiten d'Situatioun verschlechtert kënne maachen.

Selektiv Notzung vu grousse Säiten

Nodeems Dir den Artikel gelies hutt, hutt Dir festgestallt wéi eng Deeler vun Ärem Programm profitéiere kënne vu grousse Säiten ze benotzen a wéi eng net. Also sollten enorm Säiten iwwerhaapt aktivéiert ginn?

Gléck kënnt Dir benotzen madvise()fir Hugepaging nëmme fir déi Erënnerungsberäicher z'erméiglechen, wou et nëtzlech wier.

Als éischt, kontrolléiert datt hugepages am madvise () Modus leeft benotzt Instruktiounen am Ufank vum Artikel.

Dann, benotzen madvise()fir de Kernel genee ze soen, wou Dir enorm Säiten benotzt.

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

Bedenkt datt dës Method einfach Rotschléi fir de Kärel ass wéi d'Erënnerung verwalten. Dëst bedeit net datt de Kernel automatesch enorm Säiten fir eng bestëmmte Erënnerung benotzt.

Kuckt d'Dokumentatioun (Manpage)madvisefir méi iwwer Erënnerung Gestioun ze léieren an madvise(), dëst Thema huet eng onheemlech géi Léierkurve. Also wann Dir wëlles wierklech gutt drun ze ginn, preparéiert Iech fir e puer Wochen ze liesen an ze testen ier Dir positiv Resultater erwaart.

Wat ze liesen?

Hutt Dir eng Fro? Schreift an de Kommentaren!

Source: will.com

Setzt e Commentaire