Fördelar och nackdelar med HugePages

Fördelar och nackdelar med HugePages

Översättning av artikeln förberedd för kursstudenter "Linux-administratör".

Tidigare har jag pratat om hur man testar och aktiverar Hugepages på Linux.
Den här artikeln kommer bara att vara användbar om du faktiskt har en plats att använda Hugepages. Jag har träffat många människor som luras av utsikten att Hugepages på ett magiskt sätt kommer att förbättra produktiviteten. Hugeepaging är dock ett komplext ämne och kan försämra prestandan om den används felaktigt.

Del 1: Verifiera att hugepages är aktiverade på Linux (original här)

Problem:
Du måste kontrollera om HugePages är aktiverat på ditt system.

lösning:
Det är ganska enkelt:

cat /sys/kernel/mm/transparent_hugepage/enabled

Du kommer att få något sånt här:

always [madvise] never

Du kommer att se en lista över tillgängliga alternativ (alltid, galen, aldrig), och det för närvarande aktiva alternativet kommer att omges av parentes (som standard madvise).

madvise betyder att transparent hugepages endast aktiverat för minnesområden som uttryckligen begär enorma sidor med hjälp av madvise(2).

alltid betyder att transparent hugepages alltid aktiverad för alla processer. Detta förbättrar vanligtvis prestandan, men om du har ett användningsfall där många processer förbrukar en liten mängd minne, kan den totala minnesbelastningen öka dramatiskt.

aldrig betyder att transparent hugepages kommer inte att inkluderas även om det efterfrågas med madvise. För att veta mer, kontakta dokumentation Linux-kärnor.

Hur man ändrar standardvärdet

Alternativ 1: Byt direkt sysfs (efter omstart återgår parametern till sitt standardvärde):

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

Alternativ 2: Ändra systemets standard genom att kompilera om kärnan med en modifierad konfiguration (det här alternativet rekommenderas endast om du använder en anpassad kärna):

  • För att ställa in alltid som standard, använd:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • För att ställa in madvise som standard, använd:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

Del 2: Fördelar och nackdelar med HugePages

Vi kommer att försöka selektivt förklara fördelarna, nackdelarna och möjliga fallgropar med att använda Hugepages. Eftersom en tekniskt komplex och pedantisk artikel sannolikt kommer att vara svår att förstå för människor som är vilseledda att tro att Hugepages är ett universalmedel, kommer jag att offra noggrannheten för enkelheten. Det är bara värt att komma ihåg att många av ämnena är riktigt komplexa och därför avsevärt förenklade.

Observera att vi talar om 64-bitars x86-system som kör Linux, och att jag helt enkelt antar att systemet stöder transparenta hugepages (eftersom det inte är en nackdel att hugepages inte skrivs över), vilket är fallet i nästan alla moderna Linux miljö.

Jag bifogar mer teknisk beskrivning i länkarna nedan.

Virtuellt minne

Om du är en C++-programmerare vet du att objekt i minnet har specifika adresser (pekarvärden).

Dessa adresser återspeglar dock inte nödvändigtvis fysiska adresser i minnet (RAM-adresser). De representerar adresser i virtuellt minne. Processorn har en speciell MMU-modul (memory management unit) som hjälper kärnan att kartlägga virtuellt minne till en fysisk plats.

Detta tillvägagångssätt har många fördelar, men de viktigaste är:

  • Prestanda (av olika skäl);
  • Programisolering, det vill säga inget program kan läsa från ett annat programs minne.

Vad är sidor?

Virtuella minnet är uppdelat i sidor. Varje enskild sida pekar på ett specifikt fysiskt minne, den kan peka på ett område i RAM, eller den kan peka på en adress som tilldelats en fysisk enhet, till exempel ett grafikkort.

De flesta av sidorna du hanterar pekar antingen på RAM eller byts, vilket innebär att de lagras på din hårddisk eller SSD. Kärnan hanterar den fysiska layouten för varje sida. Om en falsk sida nås, stoppar kärnan tråden som försöker komma åt minnet, läser sidan från hårddisken/SSD till RAM och fortsätter sedan att köra tråden.

Denna process är strömtransparent, vilket betyder att den inte nödvändigtvis läser direkt från hårddisken/SSD. Storleken på normala sidor är 4096 byte. Storleken på stora sidor är 2 megabyte.

Översättningsassociativ buffert (TLB)

När ett program kommer åt en sida i minnet måste CPU:n veta vilken fysisk sida den ska läsa data från (det vill säga ha en virtuell adresskarta).

Kärnan har en datastruktur (sidtabell) som innehåller all information om de sidor som används. Med hjälp av denna datastruktur kan du mappa en virtuell adress till en fysisk adress.

Men sidtabellen är ganska komplex och långsam, så vi kan helt enkelt inte analysera hela datastrukturen varje gång en process kommer åt minnet.

Lyckligtvis har vår processor en TLB som cachar mappningen mellan virtuella och fysiska adresser. Detta innebär att även om vi behöver analysera sidtabellen vid det första åtkomstförsöket, kan alla efterföljande åtkomster till sidan hanteras i TLB, vilket möjliggör snabb drift.

Eftersom den är implementerad som en fysisk enhet (vilket gör den snabb i första hand) är dess kapacitet begränsad. Så om du vill komma åt fler sidor kommer TLB inte att kunna lagra mappningar för dem alla, vilket gör att ditt program går mycket långsammare.

Hugepages kommer till undsättning

Så vad kan vi göra för att undvika TLB-spill? (Vi antar att programmet fortfarande behöver samma mängd minne).

Det är här Hugepages kommer in. Istället för att 4096 byte bara kräver en TLB-post, kan en TLB-post nu peka på hela 2 megabyte. Låt oss anta att TLB har 512 poster, här utan Hugepages kan vi matcha:

4096 b⋅512=2 MB

Hur kan vi då jämföra med dem:

2 MB⋅512=1 GB

Det är därför Hugepages är fantastiskt. De kan förbättra produktiviteten utan större ansträngning. Men det finns betydande varningar här.

Hugepages spoofing

Kärnan övervakar automatiskt hur ofta varje minnessida används. Om det inte finns tillräckligt med fysiskt minne (RAM), kommer kärnan att flytta mindre viktiga (mindre ofta använda) sidor till hårddisken för att frigöra lite RAM för viktigare sidor.
Detsamma gäller i princip Hugepages. Men kärnan kan bara byta hela sidor, inte enskilda byte.

Låt oss säga att vi har ett program som detta:

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

I det här fallet kommer kärnan att behöva ersätta (läsa) så mycket som 2 megabyte information från hårddisken/SSD bara för att du ska kunna läsa en byte. Vad gäller vanliga sidor behöver bara 4096 byte läsas från hårddisken/SSD.

Därför, om hugepage åsidosätts, går det bara snabbare att läsa om du behöver komma åt hela sidan. Det betyder att om du försöker komma åt olika delar av minnet slumpmässigt och bara läser ett par kilobyte, bör du använda vanliga sidor och inte oroa dig för något annat.

Å andra sidan, om du behöver komma åt en stor del av minnet sekventiellt, kommer enorma sidor att förbättra din prestanda. Du måste dock testa det själv (inte med abstrakt programvara) och se vad som fungerar snabbare.

Tilldelning i minnet

Om du skriver C vet du att du kan begära godtyckligt små (eller nästan godtyckligt stora) mängder minne från högen med malloc(). Låt oss säga att du behöver 30 byte minne:

char* mymemory = malloc(30);

För en programmerare kan det verka som att du "begär" 30 byte minne från operativsystemet och returnerar en pekare till något virtuellt minne. Men faktiskt malloc () är bara en C-funktion som anropar inifrån funktionen brk och sbrk för att begära eller frigöra minne från operativsystemet.

Att begära mer och mer minne för varje allokering är dock ineffektivt; det är mest troligt att något minnessegment redan har frigjorts (free()), och vi kan återanvända den. malloc() implementerar ganska komplexa algoritmer för att återanvända frigjort minne.

Samtidigt händer allt obemärkt för dig, så varför skulle det oroa dig? Men eftersom utmaningen free() betyder inte det minnet returneras nödvändigtvis omedelbart till operativsystemet.

Det finns något sådant som minnesfragmentering. I extrema fall finns det heapsegment där endast ett fåtal byte används, medan allt däremellan har frigjorts (free()).

Observera att minnesfragmentering är ett otroligt komplext ämne, och även mindre ändringar av ett program kan ha en betydande inverkan. I de flesta fall kommer inte program att orsaka betydande minnesfragmentering, men du bör vara medveten om att om det finns ett problem med fragmentering i något område av högen, kan enorma sidor förvärra situationen.

Selektiv användning av enorma sidor

Efter att ha läst den här artikeln har du bestämt vilka delar av ditt program som kan dra nytta av att använda enorma sidor och vilka som inte kan. Så borde hugepages överhuvudtaget vara aktiverat?

Lyckligtvis kan du använda madvise()för att möjliggöra enorma sökningar endast för de minnesområden där det skulle vara användbart.

Kontrollera först att hugepages körs i madvise()-läge med hjälp av Avstånd i början av artikeln.

Använd sedan madvise()för att tala om för kärnan exakt var den ska använda 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)

Observera att denna metod helt enkelt är ett råd till kärnan om hur man hanterar minne. Detta betyder inte att kärnan automatiskt kommer att använda enorma sidor för ett givet minne.

Se dokumentation (manpage)madviseför att lära dig mer om minneshantering och madvise(), det här ämnet har en otroligt brant inlärningskurva. Så om du tänker bli riktigt bra på det, förbered dig på att läsa och testa i några veckor innan du förväntar dig några positiva resultat.

Vad ska man läsa?

Har en fråga? Skriv i kommentarerna!

Källa: will.com

Lägg en kommentar