A HugePages előnyei és hátrányai

A HugePages előnyei és hátrányai

A kurzus hallgatói számára készített cikk fordítása "Linux rendszergazda".

Korábban beszéltem arról, hogyan tesztelhetem és engedélyezhetem a Hugepages-t Linuxon.
Ez a cikk csak akkor lesz hasznos, ha valóban van helye a Hugepages használatára. Sok emberrel találkoztam, akiket megtéveszt az a kilátás, hogy a Hugepages varázslatosan javítani fogja a termelékenységet. A hatalmas lapozás azonban összetett téma, és ronthatja a teljesítményt, ha helytelenül használják.

1. rész: Annak ellenőrzése, hogy a hatalmas oldalak engedélyezve vannak-e Linuxon (eredeti itt)

probléma:
Ellenőriznie kell, hogy a HugePages engedélyezve van-e a rendszeren.

megoldás:
Ez elég egyszerű:

cat /sys/kernel/mm/transparent_hugepage/enabled

Valami ilyesmit fog kapni:

always [madvise] never

Megjelenik az elérhető opciók listája (mindig, madvise, soha), és a jelenleg aktív opció zárójelben lesz (alapértelmezés szerint őrült).

őrült azt jelenti, hogy transparent hugepages csak azokon a memóriaterületeken engedélyezett, amelyek kifejezetten nagy oldalakat igényelnek madvise (2).

mindig azt jelenti, hogy transparent hugepages mindig engedélyezve van minden folyamathoz. Ez általában javítja a teljesítményt, de ha olyan használati esettel rendelkezik, amikor sok folyamat kis mennyiségű memóriát fogyaszt, akkor a teljes memóriaterhelés drámaian megnőhet.

soha azt jelenti, hogy transparent hugepages akkor sem kerül bele, ha a madvise használatával kérik. További információért vegye fel a kapcsolatot dokumentáció Linux kernelek.

Az alapértelmezett érték megváltoztatása

Az 1 opció: Közvetlenül változás sysfs (újraindítás után a paraméter visszaáll az alapértelmezett értékre):

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

Az 2 opció: Módosítsa a rendszer alapértelmezett értékét a kernel módosított konfigurációval történő újrafordításával (ez a lehetőség csak akkor ajánlott, ha egyéni kernelt használ):

  • A mindig alapértelmezés szerinti beállításhoz használja:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • A madvise alapértelmezett beállításához használja:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

2. rész: A HugePages előnyei és hátrányai

Igyekszünk szelektíven elmagyarázni a Hugepages használatának előnyeit, hátrányait és lehetséges buktatóit. Mivel egy technológiailag összetett és pedáns cikket valószínűleg nehéz lesz megérteni azok számára, akik el vannak tévedve azzal, hogy a Hugepages csodaszer, ezért feláldozom a pontosságot az egyszerűségért. Csak azt érdemes szem előtt tartani, hogy sok téma nagyon összetett, ezért nagyon leegyszerűsödik.

Kérjük, vegye figyelembe, hogy Linuxot futtató 64 bites x86-os rendszerekről beszélünk, és egyszerűen abból indulok ki, hogy a rendszer támogatja az átlátszó hatalmas oldalakat (hiszen nem hátrány, hogy a hatalmas oldalakat nem írják felül), mint szinte minden modern Linuxban. környezet.

További technikai leírást mellékelek az alábbi linkeken.

Virtuális memória

Ha Ön C++ programozó, akkor tudja, hogy a memóriában lévő objektumok meghatározott címekkel (mutatóértékekkel) rendelkeznek.

Ezek a címek azonban nem feltétlenül tükrözik a memóriában lévő fizikai címeket (RAM-címeket). Címeket képviselnek a virtuális memóriában. A processzor egy speciális MMU (memóriakezelő egység) modullal rendelkezik, amely segít a kernelnek leképezni a virtuális memóriát egy fizikai helyre.

Ennek a megközelítésnek számos előnye van, de a legfontosabbak a következők:

  • Teljesítmény (különböző okokból);
  • Programizoláció, vagyis egyetlen program sem tud olvasni egy másik program memóriájából.

Mik azok az oldalak?

A virtuális memória lapokra van felosztva. Minden egyes oldal egy adott fizikai memóriára mutat, mutathat egy területet a RAM-ban, vagy mutathat egy fizikai eszközhöz, például videokártyához rendelt címre.

Az Ön által kezelt oldalak többsége vagy a RAM-ra mutat, vagy fel van cserélve, vagyis a merevlemezen vagy az SSD-n vannak tárolva. A kernel kezeli az egyes oldalak fizikai elrendezését. Hamisított oldal elérése esetén a kernel leállítja a memóriát elérni kívánó szálat, beolvassa az oldalt a merevlemezről/SSD-ről a RAM-ba, majd folytatja a szál végrehajtását.

Ez a folyamat stream-átlátszó, vagyis nem feltétlenül olvas közvetlenül a HDD/SSD-ről. A normál oldalak mérete 4096 bájt. A hatalmas oldalak mérete 2 megabájt.

Fordítás-asszociatív puffer (TLB)

Amikor egy program hozzáfér egy memóriaoldalhoz, a CPU-nak tudnia kell, hogy melyik fizikai oldalról olvassa ki az adatokat (vagyis rendelkeznie kell egy virtuális címtérképpel).

A kernelnek van egy adatstruktúrája (oldaltáblázata), amely a használt oldalakkal kapcsolatos összes információt tartalmazza. Ezzel az adatszerkezettel leképezhet egy virtuális címet egy fizikai címre.

Az oldaltábla azonban meglehetősen összetett és lassú, így egyszerűen nem tudjuk elemezni a teljes adatstruktúrát minden alkalommal, amikor egy folyamat hozzáfér a memóriához.

Szerencsére a processzorunk rendelkezik egy TLB-vel, amely gyorsítótárazza a virtuális és fizikai címek leképezését. Ez azt jelenti, hogy bár az oldaltáblázatot az első hozzáférési kísérletnél elemezni kell, az oldal minden további elérése kezelhető a TLB-ben, ami lehetővé teszi a gyors működést.

Mivel fizikai eszközként valósítják meg (ami elsősorban gyorsítja), kapacitása korlátozott. Tehát ha több oldalhoz szeretne hozzáférni, a TLB nem tudja mindegyikhez leképezést tárolni, ami miatt a program sokkal lassabban fut.

Hugepages jön a megmentésre

Mit tehetünk tehát a TLB túlcsordulás elkerülése érdekében? (Feltételezzük, hogy a programnak még mindig ugyanannyi memóriára van szüksége).

Itt jön be a Hugepages. Ahelyett, hogy 4096 bájt csak egy TLB-bejegyzést igényelne, egy TLB-bejegyzés immár hatalmas 2 megabájtra mutathat. Tegyük fel, hogy a TLB-nek 512 bejegyzése van, itt a Hugepages nélkül párosíthatunk:

4096 b⋅512=2 MB

Akkor hogyan hasonlítsuk össze őket:

2 MB⋅512=1 GB

Ezért fantasztikus a Hugepages. Nagy erőfeszítés nélkül javíthatják a termelékenységet. De vannak itt jelentős figyelmeztetések.

Hatalmas oldalak hamisítása

A kernel automatikusan figyeli, hogy az egyes memórialapokat milyen gyakran használják. Ha nincs elég fizikai memória (RAM), a kernel áthelyezi a kevésbé fontos (ritkábban használt) oldalakat a merevlemezre, hogy felszabadítson egy kis RAM-ot a fontosabb oldalak számára.
Elvileg ugyanez vonatkozik a Hugepages-re is. A kernel azonban csak teljes oldalakat tud felcserélni, egyes bájtokat nem.

Tegyük fel, hogy van egy ilyen programunk:

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

Ebben az esetben a kernelnek 2 megabájtnyi információt kell kicserélnie (beolvasnia) a merevlemezről/SSD-ről, csak hogy Ön egy bájtot beolvashasson. Ami a normál oldalakat illeti, csak 4096 bájtot kell beolvasni a merevlemezről/SSD-ről.

Ezért, ha a hatalmas oldalt felülírják, akkor csak akkor gyorsabb az olvasás, ha el kell érnie a teljes oldalt. Ez azt jelenti, hogy ha véletlenszerűen próbál hozzáférni a memória különböző részeihez, és csak néhány kilobájtot olvas, használjon szokásos oldalakat, és ne aggódjon semmi más miatt.

Másrészt, ha a memória nagy részét szekvenciálisan kell elérnie, a hatalmas oldalak javítják a teljesítményt. Azonban magának kell tesztelnie (nem absztrakt szoftverrel), és meg kell néznie, mi működik gyorsabban.

Lefoglalás a memóriában

Ha C-t ír, akkor tudja, hogy tetszőlegesen kis (vagy majdnem tetszőlegesen nagy) memóriamennyiséget kérhet a kupacból malloc(). Tegyük fel, hogy 30 bájt memóriára van szüksége:

char* mymemory = malloc(30);

A programozó számára úgy tűnhet, hogy Ön 30 bájt memóriát „kér” az operációs rendszertől, és visszaad egy mutatót valamilyen virtuális memóriára. De valójában malloc () csak egy C függvény, amely a függvényen belülről hív meg brk és sbrk memória kéréséhez vagy felszabadításához az operációs rendszertől.

Mindazonáltal nem hatékony minden egyes kiosztáshoz egyre több memóriát kérni; a legvalószínűbb, hogy bizonyos memóriaszegmensek már felszabadultak (free()), és újra felhasználhatjuk. malloc() meglehetősen összetett algoritmusokat valósít meg a felszabadult memória újrafelhasználására.

Ugyanakkor minden észrevétlenül történik számodra, miért aggódna ez? Hanem mert a kihívás free() nem azt jelenti a memória szükségszerűen azonnal visszakerül az operációs rendszerbe.

Van olyan, hogy a memória töredezettsége. Szélsőséges esetekben vannak kupacszegmensek, ahol csak néhány bájt kerül felhasználásra, miközben minden a kettő között fel van szabadítva (free()).

Kérjük, vegye figyelembe, hogy a memória töredezettsége hihetetlenül összetett téma, és még a programok kisebb módosításai is jelentős hatással lehetnek. A legtöbb esetben a programok nem okoznak jelentős memóriatöredezettséget, de tisztában kell lennie azzal, hogy ha a halom egyes területein töredezettség lép fel, a hatalmas oldalak ronthatják a helyzetet.

Hatalmas oldalak szelektív használata

A cikk elolvasása után eldöntötte, hogy programja mely részei profitálhatnak a hatalmas oldalak használatából, és melyek nem. Tehát egyáltalán engedélyezni kell a hatalmas oldalakat?

Szerencsére tudod használni madvise()hogy csak azokon a memóriaterületeken engedélyezze a hatalmas lapozást, ahol ez hasznos lenne.

Először ellenőrizze, hogy a hugepages madvise() módban fut-e a használatával utasítás a cikk elején.

Akkor használd madvise()hogy pontosan megmondja a kernelnek, hogy hol használja a hatalmas oldalakat.

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

Ne feledje, hogy ez a módszer csak tanács a kernelnek a memória kezeléséhez. Ez nem jelenti azt, hogy a kernel automatikusan hatalmas oldalakat használ egy adott memóriához.

Lásd a dokumentációt (manpage)madvisehogy többet tudjon meg a memóriakezelésről és madvise(), ennek a témának hihetetlenül meredek tanulási görbéje van. Tehát ha igazán jó akar lenni benne, készüljön fel néhány hétig az olvasásra és a tesztelésre, mielőtt bármilyen pozitív eredményt várna.

Mit kell olvasni?

Kérdése van? Írd meg kommentben!

Forrás: will.com

Hozzászólás