HugePagesтин артыкчылыктары жана кемчиликтери

HugePagesтин артыкчылыктары жана кемчиликтери

Курстун студенттери үчүн даярдалган макаланын котормосу "Linux администратору".

Буга чейин мен Linux'та Hugepagesти кантип сынап, иштетүү жөнүндө сүйлөштүм.
Бул макала сизде Hugepages колдоно турган жериңиз болсо гана пайдалуу болот. Мен Hugepages өндүрүмдүүлүгүн сыйкырдуу түрдө жакшыртат деген үмүт менен алданган көптөгөн адамдарды жолуктум. Бирок, чоң пейджинг татаал тема жана туура эмес колдонулса, иштөөнү начарлатышы мүмкүн.

1-бөлүк: Linux'та чоң баракчалар иштетилгенин текшерүү (оригинал бул жерде)

маселе:
Сиз HugePages тутумуңузда иштетилгенин текшеришиңиз керек.

чечим:
Бул абдан жөнөкөй:

cat /sys/kernel/mm/transparent_hugepage/enabled

Сиз мындай нерсени аласыз:

always [madvise] never

Сиз жеткиликтүү опциялардын тизмесин көрөсүз (дайыма, акылсыз, эч качан), жана учурда активдүү опция кашаага алынат (демейки боюнча Madvise).

Madvise дегенди билдирет transparent hugepages колдонуу менен чоң барактарды ачык талап кылган эстутум аймактары үчүн гана иштетилген Madvise(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тин артыкчылыктары жана кемчиликтери

Биз Hugepagesти колдонуунун артыкчылыктарын, кемчиликтерин жана мүмкүн болуучу тузактарын тандап түшүндүрүүгө аракет кылабыз. Технологиялык жактан татаал жана педантикалык макаланы Hugepages панацея деп ойлогон адамдар үчүн түшүнүү кыйын болгондуктан, мен жөнөкөйлүк үчүн тактыкты курман кылам. Көптөгөн темалар чындап эле татаал жана ошондуктан абдан жөнөкөйлөштүрүлгөнүн эстен чыгарбоо керек.

Сураныч, биз Linux менен иштеген 64 биттик x86 системалары жөнүндө сөз болуп жатканын жана мен жөн гана система ачык чоң баракчаларды колдойт деп болжолдоп жатам (анткени бул чоң баракчалардын үстүнөн жазылбаганы кемчилик эмес), дээрлик бардык заманбап Linux сыяктуу айлана-чөйрө.

Мен төмөндөгү шилтемелерге көбүрөөк техникалык сыпаттаманы тиркейм.

Виртуалдык Эстутум

Эгер сиз C++ программисти болсоңуз, эстутумдагы объекттердин белгилүү даректери (көрсөткүчтүн маанилери) бар экенин билесиз.

Бирок, бул даректер эстутумдагы физикалык даректерди (RAM даректери) сөзсүз түрдө чагылдырбайт. Алар виртуалдык эстутумдагы даректерди билдирет. Процессордо ядронун виртуалдык эстутумун физикалык жерге картага түшүрүүгө жардам берген атайын MMU (эстутумду башкаруу бирдиги) модулу бар.

Бул ыкманын көптөгөн артыкчылыктары бар, бирок эң негизгилери:

  • Performance (ар кандай себептерден улам);
  • Программанын изоляциясы, башкача айтканда, эч бир программа башка программанын эсинен окуй албайт.

Барактар ​​деген эмне?

Виртуалдык эс барактарга бөлүнөт. Ар бир жеке барак белгилүү бир физикалык эстутумду көрсөтөт, ал RAMдагы аймакты көрсөтө алат же видео карта сыяктуу физикалык түзүлүшкө дайындалган даректи көрсөтө алат.

Сиз менен иштеген барактардын көбү RAMды көрсөтөт же алмаштырылат, башкача айтканда, алар сиздин катуу дискиңизде же SSDде сакталат. Ядро ар бир барактын физикалык жайгашуусун башкарат. Эгерде жасалма баракка кирсе, ядро ​​эстутумга кирүүгө аракет кылган жипти токтотот, баракты катуу дисктен/SSDден RAMга окуйт, андан кийин жипти аткарууну улантат.

Бул процесс агым ачык, башкача айтканда, ал сөзсүз эле HDD/SSDден түз окулбайт. Кадимки барактардын көлөмү 4096 байт. Чоң баракчалардын көлөмү 2 мегабайт.

Котормо-ассоциативдик буфер (TLB)

Программа эстутумдун барагына киргенде, CPU кайсы физикалык барактан маалыматтарды окууну билиши керек (б.а. виртуалдык дарек картасы бар).

Ядронун маалымат структурасы (баракча таблицасы) бар, анда колдонулуп жаткан барактар ​​жөнүндө бардык маалыматтар камтылган. Бул маалымат түзүмүн колдонуу менен сиз виртуалдык даректи физикалык дарекке карталай аласыз.

Бирок, барак таблицасы абдан татаал жана жай, ошондуктан процесс эстутумга кирген сайын бүт маалымат структурасын талдай албайбыз.

Бактыга жараша, биздин процессордо виртуалдык жана физикалык даректердин ортосундагы картаны кэштеген TLB бар. Бул биринчи кирүү аракетинде барак таблицасын талдоо керек болсо да, баракка кийинки бардык кирүүлөрдү TLBде иштетүүгө болот, бул тез иштөөгө мүмкүндүк берет.

Ал физикалык түзүлүш катары ишке ашырылгандыктан (бул биринчи кезекте аны тез кылат), анын кубаттуулугу чектелген. Демек, эгер сиз көбүрөөк барактарга кирүүнү кааласаңыз, TLB алардын бардыгы үчүн карталарды сактай албайт, бул сиздин программаңыздын бир топ жайыраак иштешине алып келет.

Гугепэйс жардамга келет

Ошентип, TLB толуп кетпеш үчүн эмне кылсак болот? (Программа дагы эле бирдей көлөмдөгү эстутумга муктаж деп ойлойбуз).

Бул жерде Hugepages келет. Бир гана TLB киргизүүнү талап кылган 4096 байттын ордуна, бир TLB жазуусу эми 2 мегабайтты көрсөтө алат. Келгиле, TLBде 512 жазуу бар деп коёлу, бул жерде Hugepagesсиз биз дал келе алабыз:

4096 b⋅512=2 MB

Анан кантип алар менен салыштырсак болот:

2 MB⋅512=1 GB

Дал ушул себептен Hugepages укмуштуудай. Алар көп күч жумшабастан өндүрүмдүүлүгүн жогорулата алышат. Бирок бул жерде олуттуу эскертүүлөр бар.

Эбегейсиз спуфинг

Ядро автоматтык түрдө ар бир эстутум барагы канчалык көп колдонуларын көзөмөлдөйт. Эгерде физикалык эстутум (RAM) жетишсиз болсо, ядро ​​анча маанилүү эмес (азыраак колдонулган) барактарын катуу дискке жылдырат жана маанилүүрөөк барактар ​​үчүн оперативдүү эстутумду бошотот.
Негизи, ошол эле Hugepages тиешелүү. Бирок, ядро ​​жеке байттарды эмес, бүт барактарды гана алмаштыра алат.

Бизде мындай программа бар дейли:

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 () жөн гана С функциясы, ал функциянын ичинен чакырат брк жана сбрк операциялык тутумдан эстутумду суроо же бошотуу.

Бирок, ар бир бөлүштүрүү үчүн көбүрөөк эстутум талап кылуу натыйжасыз болуп саналат; кээ бир эс сегменти мурунтан эле бошотулган болушу мүмкүн (free()), жана биз аны кайра колдоно алабыз. malloc() бошотулган эстутумду кайра пайдалануу үчүн абдан татаал алгоритмдерди ишке ашырат.

Ошол эле учурда баары сиз үчүн байкалбастан болуп жатат, анда эмне үчүн бул сизди тынчсыздандырышы керек? Бирок, анткени кыйынчылык free() муну билдирбейт эс сөзсүз түрдө операциондук системага кайтарылып берилет.

Эстутумдун бөлүнүшү деген нерсе бар. Экстремалдуу учурларда, үймөк сегменттер бар, аларда бир нече байт гана колдонулат, ал эми ортодогу баары бошотулган. (free()).

Эсиңизде болсун, эстутумдун фрагментациясы укмуштуудай татаал тема жана программадагы кичине өзгөрүүлөр да олуттуу таасирин тийгизиши мүмкүн. Көпчүлүк учурларда, программалар эстутумдун олуттуу фрагменттелишине алып келбейт, бирок үймөктүн кандайдыр бир бөлүгүндө фрагментация көйгөйү бар болсо, чоң баракчалар кырдаалды ого бетер начарлатышы мүмкүн экенин билишиңиз керек.

Чоң баракчаларды тандап колдонуу

Бул макаланы окугандан кийин, сиз программаңыздын кайсы бөлүктөрү чоң барактарды колдонуудан пайда алып келерин, кайсынысы мүмкүн эмес экенин аныктадыңыз. Демек, чоң баракчаларды дегеле иштетиш керекпи?

Бактыга жараша, сиз колдоно аласыз madvise()пайдалуу боло турган эстутум аймактарында гана чоң баракчаларды иштетүү.

Биринчиден, bigpages 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)

Бул ыкма эстутумду кантип башкаруу боюнча ядрого жөн гана кеңеш экенин эске алыңыз. Бул өзөк автоматтык түрдө берилген эс үчүн чоң баракчаларды колдонот дегенди билдирбейт.

Документке кайрылыңыз (манбет) жинди кылууэс башкаруу жөнүндө көбүрөөк билүү үчүн жана madvise(), бул теманын укмуштуудай тик үйрөнүү ийри сызыгы бар. Андыктан, эгер сиз аны чындап жакшы үйрөнгүңүз келсе, оң натыйжаларды күтө электе бир нече жума окуп, сынап көрүүгө даярданыңыз.

Эмне окуу керек?

Суроо бар? Комментарийге жазыңыз!

Source: www.habr.com

Комментарий кошуу