
A cikk fordítása a kurzus hallgatói számára készült .
Korábban beszéltem arról, hogyan ellenőrizhető és aktiválható a HugePages használata Linux alatt.
Ez a cikk hasznos lesz, csak ha valóban van lehetősége a HugePages használatára. Sok emberbe belebotlottam, akik azt hiszik, hogy a HugePages varázslatos módon növeli a teljesítményt. Mindazonáltal a hugepaging egy összetett téma, és helytelen használat esetén csökkentheti a teljesítményt.
1. rész: Ellenőrizzük, hogy a hugepages engedélyezve van-e Linux alatt (eredeti )
Probléma:
Meg kell ellenőrizni, hogy a HugePages engedélyezve van-e a rendszerében.
Megoldás:
Ez meglehetősen egyszerű:
cat /sys/kernel/mm/transparent_hugepage/enabledValami ilyesmit fog kapni:
always [madvise] neverLátni fogja a rendelkezésre álló opciók listáját (always, madvise, never), a jelenlegi aktív opció zárójelbe lesz téve (alapértelmezés szerint madvise).
madvise azt jelenti, hogy a transparent hugepages csak azokra a memóriaterületekre vonatkozik, amelyeket kifejezetten hugepages kérnek a .
mindig azt jelenti, hogy a transparent hugepages mindig engedélyezve van, és minden folyamat számára. Ez általában növeli a teljesítményt, de ha van egy felhasználási lehetősége, ahol sok folyamat kis mennyiségű memóriát fogyaszt, akkor az összes memóriaigény hirtelen megnőhet.
soha azt jelenti, hogy a transparent hugepages nem fog aktívvá válni még a madvise kérésére sem. A további információkért hivatkozzon a Linux kernelre.
Hogyan változtassuk meg az alapértelmezett értéket
1. lehetőség: Közvetlenül módosítja 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/enabled2. lehetőség: Módosítsa a rendszer alapértelmezett értékét a kernel újrakonfigurálásával (ez az opció csak akkor ajánlott, ha saját kernelt használ):
- Ha az always-t szeretné alapértelmezetté tenni, használja:
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y # Kommentelje ki a CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y - Ha a madvise-t szeretné alapértelmezetté tenni, használja:
CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y # Kommentelje ki a CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
2. rész: A HugePages előnyei és hátrányai
Megpróbáljuk részletesen elmagyarázni a Hugepages használatának előnyeit, hátrányait és lehetséges hibáit. Mivel ez egy technológiailag összetett és precíz írás, valószínűleg nehezen érthető azok számára, akik azt hiszik, hogy a Hugepages csodaszer, az egyszerűsítés érdekében feláldozom a pontosságot. Csak annyit érdemes megjegyezni, hogy sok téma valóban bonyolult, és ezért jelentősen leegyszerűsített.
Kérjük, vegye figyelembe, hogy 64 bites x86-os rendszerekről beszélünk, amelyek Linuxon futnak, és hogy csak feltételezem, hogy a rendszer támogatja a transparent hugepages-t (mivel nem hátrány, ha a hugepages nem helyettesítések), ahogyan ez gyakorlatilag bármilyen modern Linux környezetben megtörténik.
Az alábbi linkekben további műszaki leírásokat csatolok.
Virtuális memória
Ha Ön C++ fejlesztő, tudja, hogy az objektumoknak a memóriában konkrét címei vannak (mutató értékek).
Ezek a címek azonban nem feltétlenül tükrözik a fizikai címeket a memóriában (a RAM címeket). Ezek virtuális memória címek. A processzor rendelkezik egy speciális MMU (memory management unit) modullal, amely segít a kernelnek a virtuális memória és a fizikai helyek összepárosításában.
Ez a megközelítés számos előnnyel jár, de a legfontosabbak a következők:
- Teljesítmény (különböző okok miatt);
- A programok izolációja, azaz egyik program sem tudja olvasni a másik program memóriáját.
Mi az a lap (page)?
A virtuális memória lapokra van felosztva. Minden egyes lap egy adott fizikai memóriára mutat, ez lehet egy terület a RAM-ban, vagy egy cím, amelyet egy fizikai eszköz, például egy videokártya kapott.
A legtöbb lap, amivel Ön találkozik, vagy a RAM-ra mutat, vagy swap-olt, azaz merevlemezen vagy SSD-n tárolt. A kernel kezeli minden lap fizikai elhelyezkedését. Ha egy swap-olt laphoz próbál hozzáférni, a kernel leállítja azt a szálat, amely megpróbál hozzáférni a memóriához, beolvassa a lapot a merevlemezről/SSD-ről a RAM-ba, majd folytatja a szál végrehajtását.
Ez a folyamat átlátszó a szál számára, azaz nem feltétlenül olvas közvetlenül a merevlemezről/SSD-ről. A normál lapok mérete 4096 bájt. A Hugepages mérete 2 megabájt.
Tárhelyasszociatív átkonvertáló (TLB)
Amikor a program egy bizonyos memóriaoldalhoz fordul, a központi feldolgozóegységnek tudnia kell, hogy melyik fizikai oldalról olvasson adatokat (tehát rendelkeznie kell egy virtuális címtérképpel).
A kernelben létezik egy adatszerkezet (oldaltábla), amely tartalmazza az összes információt a használt oldalakról. Ezen adatszerkezet segítségével a virtuális címet a fizikai címhez lehet hozzárendelni.
A problémát azonban az jelenti, hogy az oldaltábla eléggé bonyolult és lassan működik, ezért egyszerűen nem tudjuk folyamatosan elemezni az összes adatszerkezetet, amikor bármelyik folyamat a memóriához fordul.
Szerencsére a processzorunkban van egy TLB, amely gyorsítótárazza a virtuális és fizikai címek közötti megfeleltetést. Ez azt jelenti, hogy bár az oldaltáblát az első hozzáférési kísérletkor elemezni kell, minden további oldalra való hivatkozás a TLB-ben feldolgozható, ami gyors működést biztosít.
Mivel fizikailag eszközként valósul meg (ami elsősorban gyorssá teszi), a kapacitása korlátozott. Tehát ha több oldalhoz szeretnénk hozzáférni, a TLB nem tudja tárolni az összes megfeleltetést, ami miatt a programunk sokkal lassabban működik.
A Hugepages segíthet.
Tehát mit tehetünk a TLB túlcsordulásának elkerülése érdekében? (Feltételezzük, hogy a programnak továbbra is szüksége van ugyanarra a memória mennyiségre).
Itt jönnek a Hugepages a képbe. A 4096 bájt helyett, amely csak egy bejegyzést igényel a TLB-ben, most egy bejegyzés a TLB-ben akár 2 megabájt óriási mennyiséget is jelezhet. Tegyük fel, hogy a TLB 512 bejegyzést tartalmaz, itt Hugepages nélkül a következőképpen tudunk megfeleltetni:
4096 b⋅512=2 MBMíg velük a következőt tudjuk megfeleltetni:
2 MB⋅512=1 GBEzért a Hugepages nagyszerűek. Növelhetik a teljesítményt, jelentős erőfeszítés nélkül. De van néhány jelentős korlátozás is.
Hugepages helyettesítése
A kernel automatikusan nyomon követi minden memóriaoldal használati gyakoriságát. Ha a fizikai memória (RAM) nem elegendő, a kernel a kevésbé fontos (ritkábban használt) oldalakat áthelyezi a merevlemezre, hogy felszabadítson egy kis RAM-ot fontosabb oldalak számára.
Alapvetően ugyanez vonatkozik a Hugepages-re is. Azonban a kernel csak egész oldalakat tud áthelyezni, nem pedig külön bájtokat.
Tegyük fel, hogy van egy ilyen programunk:
char* mymemory = malloc(2*1024*1024); // Vegyük ezt egy Hugepage-nek!
// Töltsük fel mymemory-t valamilyen adatokkal
// Csináljunk sok más dolgot,
// ami a mymemory lapcseréjéhez vezet
// ...
// Kérjünk hozzáférést csak az első bájthoz
putchar(mymemory[0]); Ebben az esetben a kernelnek 2 megabájtnyi információt kell olvasnia a merevlemezen/SSD-n, csak hogy egy bájt hozzáférhető legyen. Ami a normál lapokat illeti, csupán 4096 bájt olvasása szükséges a merevlemezen/SSD-n.
Ezért, ha a hugepage lapcsere történik, annak olvasása gyorsabb, csak ha az egész laphoz kell hozzáférnie. 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 pár kilobájtot olvas, akkor a normál lapokat kell használnia, és nem kell aggódnia semmi más miatt.
Másrészt, ha nagy mennyiségű memória egyenkénti hozzáférése szükséges, a hugepages növelni fogja a teljesítményét. Mindazonáltal ezt Önnek kell kipróbálnia (nem egy elvont szoftveres példán keresztül), és megnéznie, mi működik gyorsabban.
Memóriaallokáció
Ha C nyelven programozik, tudja, hogy bármilyen kicsi (vagy szinte bármilyen nagy) memória méretet kérhet a kupacból a következő módon malloc(). Tegyük fel, hogy 30 bájt memóriára van szüksége:
char* mymemory = malloc(30);A programozónak úgy tűnhet, hogy "kér az operációs rendszertől" 30 bájt memóriát, és visszakap egy mutatót egy virtuális memória területre. De valójában malloc() csupán egy C függvény, amely belülről a függvényeket hívja meg a memória kérésére vagy felszabadítására az operációs rendszertől.
De az, hogy minden egyes allokáció során egyre több memóriát kér, nem hatékony; valószínű, hogy egy szegmens memória már felszabadult (free()), és újra felhasználható. malloc() meglehetősen összetett algoritmusokat hajt végre a felszabadított memória újrafelhasználása érdekében.
Ez azonban Önnek észrevétlenül zajlik, miért is érdekli ez Önt? Mert a free() hívás nem jelenti azt, hogy .
Van egy fogalom, amelyet memóriafragmentációnak nevezünk. Végső esetekben vannak a kupac olyan szegmensei, ahol csak néhány bájt használatos, miközben minden, ami közöttük van, már felszabadult. (free()).
Vegye figyelembe, hogy a memóriafragmentáció rendkívül összetett téma, és még a programban történt apró módosítások is jelentősen befolyásolhatják azt. A legtöbb esetben a programok nem okoznak jelentős memóriafragmentációt, de fontos szem előtt tartani, hogy ha problémák merülnek fel a kupac egyes területein a fragmentációval, a hugepages csak súlyosbíthatják a helyzetet.
Szelektív hugepages alkalmazás
Miután elolvasta a cikket, meghatározta, hogy programja mely részei profitálhatnak a hugepages használatából, és melyek nem. Érdemes tehát egyáltalán engedélyezni a hugepages-t?
Szerencsére használhatja madvise(), hogy csak azokat a memória területeket aktiválja, ahol ez hasznos lesz.
Kezdésnek ellenőrizze, hogy a hugepages a madvise() módban működik, a a cikk elején.
Ezután használja a madvise(), hogy megmondja a kernelnak, hol használja a hugepages-t.
#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 ajánlás a kernel számára a memóriakezeléshez. Ez nem jelenti azt, hogy a kernel automatikusan fogja használni a hugepages-t a megadott memória számára.
Olvassa el a dokumentációt , hogy többet tudjon meg a memóriakezelésről, és madvise(), ennek a témának rendkívül meredek tanulási görbéje van. Ezért, ha valóban alaposan szeretné megérteni, készüljön fel arra, hogy hetekig olvasson és teszteljen, mielőtt bármilyen pozitív eredményre számítana.
Mit érdemes olvasni?
Van kérdése? Írjon a megjegyzésekbe!
Forrás: habr.com
