భారీ పేజీల యొక్క ప్రయోజనాలు మరియు అప్రయోజనాలు

భారీ పేజీల యొక్క ప్రయోజనాలు మరియు అప్రయోజనాలు

కోర్సు విద్యార్థుల కోసం తయారు చేసిన వ్యాసం యొక్క అనువాదం "Linux అడ్మినిస్ట్రేటర్".

ఇంతకుముందు, నేను Linuxలో Hugepagesని ఎలా పరీక్షించాలి మరియు ప్రారంభించాలి అనే దాని గురించి మాట్లాడాను.
మీకు నిజంగా హ్యూజ్‌పేజీలను ఉపయోగించడానికి స్థలం ఉంటే మాత్రమే ఈ కథనం ఉపయోగకరంగా ఉంటుంది. Hugepages ఉత్పాదకతను అద్భుతంగా మెరుగుపరుస్తాయనే అంచనాతో మోసపోయిన చాలా మంది వ్యక్తులను నేను కలుసుకున్నాను. అయినప్పటికీ, భారీ పేజింగ్ అనేది సంక్లిష్టమైన అంశం మరియు తప్పుగా ఉపయోగించినట్లయితే పనితీరును తగ్గించవచ్చు.

పార్ట్ 1: Linuxలో భారీ పేజీలు ప్రారంభించబడి ఉన్నాయని ధృవీకరించడం (అసలు ఇక్కడ)

సమస్య:
మీ సిస్టమ్‌లో HugePages ప్రారంభించబడిందో లేదో మీరు తనిఖీ చేయాలి.

పరిష్కారం:
ఇది చాలా సులభం:

cat /sys/kernel/mm/transparent_hugepage/enabled

మీరు ఇలాంటివి పొందుతారు:

always [madvise] never

మీరు అందుబాటులో ఉన్న ఎంపికల జాబితాను చూస్తారు (ఎల్లప్పుడూ, పిచ్చి, ఎప్పుడూ), మరియు ప్రస్తుతం క్రియాశీల ఎంపిక కుండలీకరణాల్లో (డిఫాల్ట్‌గా) జతచేయబడుతుంది పిచ్చిపిచ్చి).

పిచ్చిపిచ్చి దాని అర్ధము transparent hugepages ఉపయోగించి భారీ పేజీలను స్పష్టంగా అభ్యర్థించే మెమరీ ప్రాంతాలకు మాత్రమే ప్రారంభించబడింది పిచ్చి (2).

ఎల్లప్పుడూ దాని అర్ధము transparent hugepages అన్ని ప్రక్రియల కోసం ఎల్లప్పుడూ ప్రారంభించబడుతుంది. ఇది సాధారణంగా పనితీరును మెరుగుపరుస్తుంది, అయితే మీరు అనేక ప్రక్రియలు తక్కువ మొత్తంలో మెమరీని వినియోగించే వినియోగ సందర్భాన్ని కలిగి ఉంటే, మొత్తం మెమరీ లోడ్ నాటకీయంగా పెరుగుతుంది.

ఎప్పుడూ దాని అర్ధము transparent hugepages madviseని ఉపయోగించి అభ్యర్థించినప్పుడు కూడా చేర్చబడదు. మరింత తెలుసుకోవడానికి, సంప్రదించండి డాక్యుమెంటేషన్ Linux కెర్నలు.

డిఫాల్ట్ విలువను ఎలా మార్చాలి

ఎంపిక 1: నేరుగా మార్చండి sysfs (రీబూట్ చేసిన తర్వాత పరామితి దాని డిఫాల్ట్ విలువకు తిరిగి వస్తుంది):

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

ఎంపిక 2: సవరించిన కాన్ఫిగరేషన్‌తో కెర్నల్‌ను తిరిగి కంపైల్ చేయడం ద్వారా సిస్టమ్ డిఫాల్ట్‌ను మార్చండి (మీరు అనుకూల కెర్నల్‌ని ఉపయోగిస్తుంటే మాత్రమే ఈ ఐచ్ఛికం సిఫార్సు చేయబడుతుంది):

  • ఎల్లప్పుడూ డిఫాల్ట్‌గా సెట్ చేయడానికి, ఉపయోగించండి:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • madviseని డిఫాల్ట్‌గా సెట్ చేయడానికి, ఉపయోగించండి:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

పార్ట్ 2: భారీ పేజీల ప్రయోజనాలు మరియు అప్రయోజనాలు

మేము Hugepagesని ఉపయోగించడం వల్ల కలిగే ప్రయోజనాలు, అప్రయోజనాలు మరియు సాధ్యమయ్యే నష్టాలను ఎంపిక చేసి వివరించడానికి ప్రయత్నిస్తాము. హ్యూజ్‌పేజ్‌లు సర్వరోగ నివారిణిగా భావించి భ్రమపడుతున్న వ్యక్తులకు సాంకేతికంగా సంక్లిష్టమైన మరియు నిష్కపటమైన కథనాన్ని అర్థం చేసుకోవడం కష్టం కాబట్టి, నేను సరళత కోసం ఖచ్చితత్వాన్ని త్యాగం చేస్తాను. చాలా విషయాలు చాలా క్లిష్టంగా ఉన్నాయని మరియు అందువల్ల చాలా సరళంగా ఉన్నాయని గుర్తుంచుకోవడం విలువ.

దయచేసి మేము Linuxని నడుపుతున్న 64-bit x86 సిస్టమ్‌ల గురించి మాట్లాడుతున్నామని మరియు దాదాపు ఏ ఆధునిక Linuxలో మాదిరిగానే సిస్టమ్ పారదర్శక భారీ పేజీలకు (భారీ పేజీలు భర్తీ చేయకపోవడం ప్రతికూలత కాదు కాబట్టి) మద్దతు ఇస్తుందని నేను ఊహిస్తున్నాను. పర్యావరణం.

నేను దిగువ లింక్‌లలో మరింత సాంకేతిక వివరణను జతచేస్తాను.

వర్చువల్ మెమరీ

మీరు C++ ప్రోగ్రామర్ అయితే, మెమరీలోని వస్తువులు నిర్దిష్ట చిరునామాలను (పాయింటర్ విలువలు) కలిగి ఉంటాయని మీకు తెలుసు.

అయినప్పటికీ, ఈ చిరునామాలు మెమరీలోని భౌతిక చిరునామాలను తప్పనిసరిగా ప్రతిబింబించవు (RAM చిరునామాలు). అవి వర్చువల్ మెమరీలో చిరునామాలను సూచిస్తాయి. ప్రాసెసర్ ఒక ప్రత్యేక MMU (మెమరీ మేనేజ్‌మెంట్ యూనిట్) మాడ్యూల్‌ను కలిగి ఉంది, ఇది కెర్నల్ వర్చువల్ మెమరీని భౌతిక స్థానానికి మ్యాప్ చేయడంలో సహాయపడుతుంది.

ఈ విధానం అనేక ప్రయోజనాలను కలిగి ఉంది, కానీ చాలా ముఖ్యమైనవి:

  • పనితీరు (వివిధ కారణాల వల్ల);
  • ప్రోగ్రామ్ ఐసోలేషన్, అంటే ఏ ప్రోగ్రామ్ మరొక ప్రోగ్రామ్ మెమరీ నుండి చదవదు.

పేజీలు అంటే ఏమిటి?

వర్చువల్ మెమరీ పేజీలుగా విభజించబడింది. ప్రతి వ్యక్తిగత పేజీ నిర్దిష్ట భౌతిక మెమరీని సూచిస్తుంది, ఇది RAMలోని ప్రాంతాన్ని సూచించవచ్చు లేదా వీడియో కార్డ్ వంటి భౌతిక పరికరానికి కేటాయించిన చిరునామాను సూచించవచ్చు.

మీరు వ్యవహరించే చాలా పేజీలు RAMకి పాయింట్ లేదా మార్పిడి చేయబడ్డాయి, అంటే అవి మీ హార్డ్ డ్రైవ్ లేదా SSDలో నిల్వ చేయబడతాయి. కెర్నల్ ప్రతి పేజీ యొక్క భౌతిక లేఅవుట్‌ను నిర్వహిస్తుంది. స్పూఫ్డ్ పేజీ యాక్సెస్ చేయబడితే, మెమరీని యాక్సెస్ చేయడానికి ప్రయత్నిస్తున్న థ్రెడ్‌ను కెర్నల్ ఆపివేస్తుంది, హార్డ్ డ్రైవ్/SSD నుండి RAM లోకి పేజీని రీడ్ చేసి, ఆపై థ్రెడ్‌ని అమలు చేయడం కొనసాగిస్తుంది.

ఈ ప్రక్రియ పారదర్శకంగా ప్రసారం చేయబడుతుంది, అంటే ఇది HDD/SSD నుండి నేరుగా చదవాల్సిన అవసరం లేదు. సాధారణ పేజీల పరిమాణం 4096 బైట్లు. భారీ పేజీల పరిమాణం 2 మెగాబైట్లు.

అనువాదం-అనుబంధ బఫర్ (TLB)

ప్రోగ్రామ్ మెమరీ పేజీని యాక్సెస్ చేసినప్పుడు, CPU తప్పనిసరిగా ఏ భౌతిక పేజీ నుండి డేటాను చదవాలో తెలుసుకోవాలి (అంటే, వర్చువల్ అడ్రస్ మ్యాప్ ఉండాలి).

కెర్నల్ డేటా స్ట్రక్చర్ (పేజీ పట్టిక)ని కలిగి ఉంది, అది ఉపయోగించబడుతున్న పేజీల గురించిన మొత్తం సమాచారాన్ని కలిగి ఉంటుంది. ఈ డేటా నిర్మాణాన్ని ఉపయోగించి, మీరు వర్చువల్ చిరునామాను భౌతిక చిరునామాకు మ్యాప్ చేయవచ్చు.

అయినప్పటికీ, పేజీ పట్టిక చాలా క్లిష్టమైనది మరియు నెమ్మదిగా ఉంటుంది, కాబట్టి ప్రాసెస్ మెమరీని యాక్సెస్ చేసిన ప్రతిసారీ మేము మొత్తం డేటా నిర్మాణాన్ని విశ్లేషించలేము.

అదృష్టవశాత్తూ, మా ప్రాసెసర్‌లో వర్చువల్ మరియు భౌతిక చిరునామాల మధ్య మ్యాపింగ్‌ను కాష్ చేసే TLB ఉంది. దీనర్థం మనం మొదటి యాక్సెస్ ప్రయత్నంలో పేజీ పట్టికను అన్వయించవలసి ఉన్నప్పటికీ, పేజీకి సంబంధించిన అన్ని తదుపరి యాక్సెస్‌లను TLBలో నిర్వహించవచ్చు, ఇది వేగవంతమైన ఆపరేషన్‌కు వీలు కల్పిస్తుంది.

ఇది భౌతిక పరికరంగా అమలు చేయబడినందున (ఇది మొదటి స్థానంలో వేగంగా పని చేస్తుంది), దాని సామర్థ్యం పరిమితం. కాబట్టి మీరు మరిన్ని పేజీలను యాక్సెస్ చేయాలనుకుంటే, TLB అన్నింటికీ మ్యాపింగ్‌లను నిల్వ చేయదు, దీని వలన మీ ప్రోగ్రామ్ చాలా నెమ్మదిగా నడుస్తుంది.

భారీ పేజీలు రక్షించటానికి వస్తాయి

కాబట్టి TLB ఓవర్‌ఫ్లో నివారించడానికి మనం ఏమి చేయవచ్చు? (ప్రోగ్రామ్‌కి ఇప్పటికీ అదే మొత్తంలో మెమరీ అవసరమని మేము అనుకుంటాము).

ఇక్కడే భారీ పేజీలు వస్తాయి. కేవలం ఒక TLB ఎంట్రీ అవసరమయ్యే 4096 బైట్‌లకు బదులుగా, ఒక TLB ఎంట్రీ ఇప్పుడు భారీ 2 మెగాబైట్‌లను సూచించగలదు. TLBకి 512 ఎంట్రీలు ఉన్నాయని అనుకుందాం, ఇక్కడ భారీ పేజీలు లేకుండా మనం సరిపోలవచ్చు:

4096 b⋅512=2 MB

అప్పుడు మనం వారితో ఎలా పోల్చవచ్చు:

2 MB⋅512=1 GB

అందుకే భారీపేజీలు అద్భుతంగా ఉన్నాయి. వారు ఎక్కువ శ్రమ లేకుండా ఉత్పాదకతను మెరుగుపరుస్తారు. కానీ ఇక్కడ ముఖ్యమైన హెచ్చరికలు ఉన్నాయి.

భారీ పేజీలు స్పూఫింగ్

ప్రతి మెమరీ పేజీ ఎంత తరచుగా ఉపయోగించబడుతుందో కెర్నల్ స్వయంచాలకంగా పర్యవేక్షిస్తుంది. తగినంత ఫిజికల్ మెమరీ (RAM) లేకపోతే, కెర్నల్ తక్కువ ముఖ్యమైన (తక్కువ తరచుగా ఉపయోగించే) పేజీలను హార్డ్ డిస్క్‌కి తరలించి మరింత ముఖ్యమైన పేజీల కోసం కొంత RAMని ఖాళీ చేస్తుంది.
సూత్రప్రాయంగా, అదే భారీపేజీలకు వర్తిస్తుంది. అయినప్పటికీ, కెర్నల్ మొత్తం పేజీలను మాత్రమే మార్చుకోగలదు, వ్యక్తిగత బైట్‌లను కాదు.

మనకు ఇలాంటి ప్రోగ్రామ్ ఉందని చెప్పండి:

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

ఈ సందర్భంలో, మీరు ఒక బైట్ చదవడం కోసం హార్డ్ డ్రైవ్/SSD నుండి కెర్నల్ 2 మెగాబైట్‌ల సమాచారాన్ని భర్తీ చేయాలి (చదవాలి). సాధారణ పేజీల కొరకు, హార్డ్ డ్రైవ్/SSD నుండి 4096 బైట్‌లను మాత్రమే చదవాలి.

కాబట్టి, భారీపేజీ భర్తీ చేయబడితే, మీరు మొత్తం పేజీని యాక్సెస్ చేయవలసి వస్తే మాత్రమే చదవడం వేగంగా ఉంటుంది. దీనర్థం మీరు యాదృచ్ఛికంగా మెమరీలోని వివిధ భాగాలను యాక్సెస్ చేయడానికి ప్రయత్నిస్తుంటే మరియు కేవలం రెండు కిలోబైట్‌లను చదువుతుంటే, మీరు సాధారణ పేజీలను ఉపయోగించాలి మరియు మరేదైనా చింతించకూడదు.

మరోవైపు, మీరు మెమరీలో ఎక్కువ భాగాన్ని సీక్వెన్షియల్‌గా యాక్సెస్ చేయవలసి వస్తే, భారీ పేజీలు మీ పనితీరును మెరుగుపరుస్తాయి. అయితే, మీరు దీన్ని మీరే పరీక్షించుకోవాలి (నైరూప్య సాఫ్ట్‌వేర్‌తో కాదు) మరియు ఏది వేగంగా పని చేస్తుందో చూడండి.

మెమరీలో కేటాయింపు

మీరు C వ్రాస్తే, మీరు హీప్ నుండి ఏకపక్షంగా చిన్న (లేదా దాదాపు ఏకపక్షంగా పెద్ద) మెమరీని అభ్యర్థించవచ్చని మీకు తెలుసు malloc(). మీకు 30 బైట్ల మెమరీ అవసరమని చెప్పండి:

char* mymemory = malloc(30);

ప్రోగ్రామర్‌కు, మీరు ఆపరేటింగ్ సిస్టమ్ నుండి 30 బైట్‌ల మెమరీని "అభ్యర్థిస్తున్నట్లు" మరియు కొంత వర్చువల్ మెమరీకి పాయింటర్‌ను తిరిగి ఇస్తున్నట్లు కనిపించవచ్చు. కానీ నిజానికి malloc () కేవలం ఒక C ఫంక్షన్ ఫంక్షన్ లోపల నుండి కాల్ చేస్తుంది brk మరియు sbrk ఆపరేటింగ్ సిస్టమ్ నుండి మెమరీని అభ్యర్థించడానికి లేదా ఖాళీ చేయడానికి.

అయితే, ప్రతి కేటాయింపు కోసం మరింత ఎక్కువ మెమరీని అభ్యర్థించడం అసమర్థమైనది; కొంత మెమరీ సెగ్మెంట్ ఇప్పటికే విడుదల చేయబడి ఉండవచ్చు (free()), మరియు మేము దానిని తిరిగి ఉపయోగించుకోవచ్చు. malloc() ఫ్రీడ్ మెమరీని తిరిగి ఉపయోగించడం కోసం చాలా క్లిష్టమైన అల్గారిథమ్‌లను అమలు చేస్తుంది.

అదే సమయంలో, ప్రతిదీ మీకు కనిపించకుండానే జరుగుతుంది, కాబట్టి మీరు ఎందుకు చింతించాలి? కానీ సవాలు ఎందుకంటే free() అని అర్థం కాదు మెమరీ తప్పనిసరిగా వెంటనే ఆపరేటింగ్ సిస్టమ్‌కు తిరిగి ఇవ్వబడుతుంది.

మెమరీ ఫ్రాగ్మెంటేషన్ వంటి విషయం ఉంది. విపరీతమైన సందర్భాల్లో, కొన్ని బైట్‌లు మాత్రమే ఉపయోగించబడే హీప్ సెగ్మెంట్‌లు ఉన్నాయి, అయితే మధ్యలో ఉన్న ప్రతిదీ విముక్తి చేయబడింది (free()).

మెమరీ ఫ్రాగ్మెంటేషన్ అనేది చాలా క్లిష్టమైన అంశం మరియు ప్రోగ్రామ్‌లో చిన్న మార్పులు కూడా గణనీయమైన ప్రభావాన్ని చూపుతాయని దయచేసి గమనించండి. చాలా సందర్భాలలో, ప్రోగ్రామ్‌లు గణనీయమైన మెమరీ ఫ్రాగ్మెంటేషన్‌కు కారణం కాదు, అయితే కుప్పలోని కొంత ప్రాంతంలో ఫ్రాగ్మెంటేషన్‌లో సమస్య ఉంటే, భారీ పేజీలు పరిస్థితిని మరింత దిగజార్చగలవని మీరు తెలుసుకోవాలి.

భారీ పేజీల ఎంపిక ఉపయోగం

ఈ కథనాన్ని చదివిన తర్వాత, మీ ప్రోగ్రామ్‌లోని ఏ భాగాలు భారీ పేజీలను ఉపయోగించడం ద్వారా ప్రయోజనం పొందవచ్చో మరియు ఏవి చేయలేవని మీరు నిర్ణయించారు. కాబట్టి భారీ పేజీలను ప్రారంభించాలా?

అదృష్టవశాత్తూ మీరు ఉపయోగించవచ్చు madvise()ఇది ఉపయోగకరంగా ఉండే మెమరీ ప్రాంతాలకు మాత్రమే భారీ పేజింగ్‌ని ప్రారంభించడానికి.

ముందుగా, భారీపేజీలు madvise() మోడ్‌లో అమలవుతున్నాయో లేదో తనిఖీ చేయండి సూచనలను వ్యాసం ప్రారంభంలో.

అప్పుడు, ఉపయోగించండి madvise()భారీ పేజీలను ఎక్కడ ఉపయోగించాలో కెర్నల్‌కు ఖచ్చితంగా చెప్పడానికి.

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

ఈ పద్ధతి మెమరీని ఎలా నిర్వహించాలో కెర్నల్‌కు కేవలం సలహా మాత్రమేనని గమనించండి. ఇచ్చిన మెమరీ కోసం కెర్నల్ స్వయంచాలకంగా భారీ పేజీలను ఉపయోగిస్తుందని దీని అర్థం కాదు.

డాక్యుమెంటేషన్ చూడండి (manpage)madviseమెమరీ నిర్వహణ గురించి మరింత తెలుసుకోవడానికి మరియు madvise(), ఈ అంశం చాలా నిటారుగా నేర్చుకునే వక్రతను కలిగి ఉంది. కాబట్టి మీరు నిజంగా మంచిగా ఉండాలనుకుంటే, మీరు ఏదైనా సానుకూల ఫలితాలను ఆశించే ముందు కొన్ని వారాల పాటు చదివి పరీక్షించడానికి సిద్ధం చేయండి.

ఏం చదవాలి?

ప్రశ్న ఉందా? వ్యాఖ్యలలో వ్రాయండి!

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి