Fordele og ulemper ved HugePages

Fordele og ulemper ved HugePages

Oversættelse af artiklen udarbejdet til kursister "Linux-administrator".

Tidligere talte jeg om, hvordan man tester og aktiverer Hugepages på Linux.
Denne artikel vil kun være nyttig, hvis du rent faktisk har et sted at bruge Hugepages. Jeg har mødt en masse mennesker, der er blevet narret af udsigten til, at Hugepages på magisk vis vil forbedre produktiviteten. Hugepaging er dog et komplekst emne og kan forringe ydeevnen, hvis den bruges forkert.

Del 1: Bekræftelse af, at hugepages er aktiveret på Linux (original her)

problem:
Du skal kontrollere, om HugePages er aktiveret på dit system.

opløsning:
Det er ret simpelt:

cat /sys/kernel/mm/transparent_hugepage/enabled

Du får noget som dette:

always [madvise] never

Du vil se en liste over tilgængelige muligheder (altid, gale, aldrig), og den aktuelt aktive indstilling vil være omgivet af parentes (som standard madvise).

madvise betyder at transparent hugepages kun aktiveret for hukommelsesområder, der eksplicit anmoder om enorme sider ved hjælp af madvise(2).

altid betyder at transparent hugepages altid aktiveret for alle processer. Dette forbedrer normalt ydeevnen, men hvis du har en use case, hvor mange processer bruger en lille mængde hukommelse, så kan den samlede hukommelsesbelastning stige dramatisk.

aldrig betyder at transparent hugepages vil ikke være inkluderet, selv når der anmodes om det ved hjælp af madvise. For at få mere at vide, kontakt dokumentation Linux kerner.

Sådan ændres standardværdien

Mulighed 1: Skift direkte sysfs (efter genstart vender parameteren tilbage til standardværdien):

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

Mulighed 2: Skift systemets standard ved at rekompilere kernen med en ændret konfiguration (denne mulighed anbefales kun, hvis du bruger en brugerdefineret kerne):

  • For at indstille altid som standard, brug:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • For at indstille madvise som standard, brug:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

Del 2: Fordele og ulemper ved HugePages

Vi vil forsøge selektivt at forklare fordele, ulemper og mulige faldgruber ved at bruge Hugepages. Da en teknologisk kompleks og pedantisk artikel sandsynligvis vil være svær at forstå for folk, der er vildledt til at tro, at Hugepages er et vidundermiddel, vil jeg ofre nøjagtigheden for enkelheden. Det er bare værd at huske på, at mange af emnerne er virkelig komplekse og derfor meget forenklede.

Bemærk venligst, at vi taler om 64-bit x86-systemer, der kører Linux, og at jeg blot antager, at systemet understøtter gennemsigtige hugepages (da det ikke er en ulempe, at hugepages ikke overskrives), som det er tilfældet i næsten enhver moderne Linux miljø.

Jeg vil vedhæfte mere teknisk beskrivelse i nedenstående links.

Virtuel hukommelse

Hvis du er en C++ programmør, ved du, at objekter i hukommelsen har specifikke adresser (pointerværdier).

Disse adresser afspejler dog ikke nødvendigvis fysiske adresser i hukommelsen (RAM-adresser). De repræsenterer adresser i virtuel hukommelse. Processoren har et specielt MMU (memory management unit) modul, der hjælper kernen med at kortlægge virtuel hukommelse til en fysisk placering.

Denne tilgang har mange fordele, men de vigtigste er:

  • Ydeevne (af forskellige årsager);
  • Programisolation, det vil sige, at intet program kan læse fra et andet programs hukommelse.

Hvad er sider?

Virtuel hukommelse er opdelt i sider. Hver enkelt side peger på en bestemt fysisk hukommelse, den kan pege på et område i RAM, eller den kan pege på en adresse, der er tildelt en fysisk enhed, såsom et videokort.

De fleste af de sider, du beskæftiger dig med, peger enten på RAM eller er ombyttet, hvilket betyder, at de er gemt på din harddisk eller SSD. Kernen styrer det fysiske layout af hver side. Hvis der tilgås en forfalsket side, stopper kernen tråden, der forsøger at få adgang til hukommelsen, læser siden fra harddisken/SSD'en ind i RAM og fortsætter derefter med at udføre tråden.

Denne proces er strømgennemsigtig, hvilket betyder, at den ikke nødvendigvis læser direkte fra HDD'en/SSD'en. Størrelsen på normale sider er 4096 bytes. Hugepages størrelse er 2 megabyte.

Translation-associative buffer (TLB)

Når et program får adgang til en hukommelsesside, skal CPU'en vide, hvilken fysisk side den skal læse data fra (det vil sige have et virtuelt adressekort).

Kernen har en datastruktur (sidetabel), der indeholder al information om de sider, der bruges. Ved hjælp af denne datastruktur kan du knytte en virtuel adresse til en fysisk adresse.

Sidetabellen er dog ret kompleks og langsom, så vi kan simpelthen ikke analysere hele datastrukturen hver gang en proces får adgang til hukommelsen.

Heldigvis har vores processor en TLB, der cacher kortlægningen mellem virtuelle og fysiske adresser. Dette betyder, at selvom vi skal parse sidetabellen ved det første adgangsforsøg, kan alle efterfølgende adgange til siden håndteres i TLB, hvilket giver mulighed for hurtig drift.

Fordi den er implementeret som en fysisk enhed (hvilket gør den hurtig i første omgang), er dens kapacitet begrænset. Så hvis du vil have adgang til flere sider, vil TLB ikke være i stand til at gemme kortlægninger for dem alle, hvilket får dit program til at køre meget langsommere.

Hugepages kommer til undsætning

Så hvad kan vi gøre for at undgå TLB-overløb? (Vi antager, at programmet stadig har brug for den samme mængde hukommelse).

Det er her Hugepages kommer ind i billedet. I stedet for at 4096 bytes kun kræver en TLB-indgang, kan en TLB-indgang nu pege på hele 2 megabyte. Lad os antage, at TLB har 512 poster, her uden Hugepages kan vi matche:

4096 b⋅512=2 MB

Hvordan kan vi så sammenligne med dem:

2 MB⋅512=1 GB

Det er derfor, Hugepages er fantastisk. De kan forbedre produktiviteten uden stor indsats. Men der er væsentlige forbehold her.

Hugepages spoofing

Kernen overvåger automatisk, hvor ofte hver hukommelsesside bruges. Hvis der ikke er nok fysisk hukommelse (RAM), vil kernen flytte mindre vigtige (mindre brugte) sider til harddisken for at frigøre noget RAM til vigtigere sider.
I princippet gælder det samme for Hugepages. Men kernen kan kun bytte hele sider, ikke individuelle bytes.

Lad os sige, at vi har et program som dette:

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

I dette tilfælde skal kernen erstatte (læse) så meget som 2 megabyte information fra harddisken/SSD'en, bare for at du kan læse en byte. Hvad angår almindelige sider, skal der kun læses 4096 bytes fra harddisken/SSD'en.

Hvis hugepage tilsidesættes, er det derfor kun hurtigere at læse, hvis du skal have adgang til hele siden. Det betyder, at hvis du forsøger at tilfældigt få adgang til forskellige dele af hukommelsen og bare læser et par kilobyte, bør du bruge almindelige sider og ikke bekymre dig om andet.

På den anden side, hvis du har brug for at få adgang til en stor del af hukommelsen sekventielt, vil enorme sider forbedre din ydeevne. Du skal dog selv teste det (ikke med abstrakt software) og se, hvad der virker hurtigere.

Tildeling i hukommelsen

Hvis du skriver C, ved du, at du kan anmode om vilkårligt små (eller næsten vilkårligt store) mængder hukommelse fra heapen vha. malloc(). Lad os sige, at du har brug for 30 bytes hukommelse:

char* mymemory = malloc(30);

For en programmør kan det se ud til, at du "anmoder" om 30 bytes hukommelse fra operativsystemet og returnerer en pointer til en virtuel hukommelse. Men faktisk malloc () er blot en C-funktion, der kalder inde fra funktionen brk og sbrk for at anmode om eller frigøre hukommelse fra operativsystemet.

Det er imidlertid ineffektivt at anmode om mere og mere hukommelse for hver tildeling; det er højst sandsynligt, at et eller andet hukommelsessegment allerede er frigivet (free()), og vi kan genbruge det. malloc() implementerer ret komplekse algoritmer til genbrug af frigjort hukommelse.

Samtidig sker alt ubemærket for dig, så hvorfor skulle det bekymre dig? Men fordi udfordringen free() betyder det ikke hukommelse returneres nødvendigvis øjeblikkeligt til operativsystemet.

Der er sådan noget som hukommelsesfragmentering. I ekstreme tilfælde er der heap-segmenter, hvor der kun bruges nogle få bytes, mens alt derimellem er blevet frigivet (free()).

Bemærk venligst, at hukommelsesfragmentering er et utroligt komplekst emne, og selv mindre ændringer i et program kan have en betydelig indvirkning. I de fleste tilfælde vil programmer ikke forårsage væsentlig hukommelsesfragmentering, men du skal være opmærksom på, at hvis der er et problem med fragmentering i et eller andet område af heapen, kan enorme sider gøre situationen værre.

Selektiv brug af enorme sider

Efter at have læst artiklen har du fundet ud af, hvilke dele af dit program der kan drage fordel af at bruge hugepages, og hvilke der ikke kan. Skal hugepages overhovedet aktiveres?

Heldigvis kan du bruge madvise()at aktivere hugepaging kun for de hukommelsesområder, hvor det ville være nyttigt.

Først skal du kontrollere, at hugepages kører i madvise()-tilstand ved hjælp af Kørselsvejledning i begyndelsen af ​​artiklen.

Brug derefter madvise()at fortælle kernen præcis, hvor den skal bruge 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)

Bemærk, at denne metode blot er et råd til kernen om, hvordan man administrerer hukommelse. Dette betyder ikke, at kernen automatisk vil bruge enorme sider til en given hukommelse.

Se dokumentation (manpage)madvisefor at lære mere om hukommelseshåndtering og madvise(), dette emne har en utrolig stejl indlæringskurve. Så hvis du har til hensigt at blive rigtig god til det, så forbered dig på at læse og teste i et par uger, før du forventer positive resultater.

Hvad skal man læse?

Har du et spørgsmål? Skriv i kommentarerne!

Kilde: www.habr.com

Tilføj en kommentar