Предности и недостаци ХугеПагес

Предности и недостаци ХугеПагес

Превод чланка припремљен за студенте курса "Линук администратор".

Раније сам говорио о томе како да тестирам и омогућим Хугепагес на Линук-у.
Овај чланак ће бити користан само ако заиста имате место да користите Хугепагес. Упознао сам много људи који су преварени изгледом да ће Хугепагес магично побољшати продуктивност. Међутим, огромна страница је сложена тема и може смањити перформансе ако се користи неправилно.

Део 1: Провера да су огромне странице омогућене на Линук-у (оригинално овде)

Проблем:
Морате да проверите да ли је ХугеПагес омогућен на вашем систему.

rešenje:
Прилично је једноставно:

cat /sys/kernel/mm/transparent_hugepage/enabled

Добићете нешто овако:

always [madvise] never

Видећете листу доступних опција (увек, лудо, никад), а тренутно активна опција ће бити затворена у заградама (подразумевано мадвисе).

мадвисе значи да transparent hugepages омогућено само за меморијске области које експлицитно захтевају огромне странице користећи мадвисе (2).

увек значи да transparent hugepages увек омогућен за све процесе. Ово обично побољшава перформансе, али ако имате случај употребе у којем многи процеси троше малу количину меморије, онда се укупно оптерећење меморије може драматично повећати.

никад значи да transparent hugepages неће бити укључено чак ни када се то захтева коришћењем мадвисе-а. Да бисте сазнали више, контактирајте документација Линук кернели.

Како променити подразумевану вредност

Опција КСНУМКС: Директно променити 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

Опција КСНУМКС: Промените подразумевани систем тако што ћете поново компајлирати кернел са модификованом конфигурацијом (ова опција се препоручује само ако користите прилагођено језгро):

  • Да бисте увек подесили подразумевано, користите:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • Да бисте поставили мадвисе као подразумевани, користите:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

Део 2: Предности и недостаци ХугеПагес

Покушаћемо да селективно објаснимо предности, недостатке и могуће замке коришћења Хугепагес. Пошто ће технолошки сложен и педантан чланак вероватно бити тешко разумети људима који се заваравају мислећи да је Хугепагес лек, жртвоваћу прецизност ради једноставности. Само вреди имати на уму да су многе теме заиста сложене и стога веома поједностављене.

Имајте на уму да говоримо о 64-битним к86 системима који користе Линук, и да једноставно претпостављам да систем подржава транспарентне огромне странице (пошто није недостатак што се огромне странице не преписују), као што је случај у скоро сваком модерном Линуку Животна средина.

Приложићу више техничког описа на линковима испод.

Виртуелна меморија

Ако сте Ц++ програмер, знате да објекти у меморији имају специфичне адресе (вредности показивача).

Међутим, ове адресе не одражавају нужно физичке адресе у меморији (РАМ адресе). Они представљају адресе у виртуелној меморији. Процесор има посебан ММУ (мемори манагемент унит) модул који помаже кернелу да мапира виртуелну меморију на физичку локацију.

Овај приступ има много предности, али најважније су:

  • Перформансе (из разних разлога);
  • Изолација програма, односно ниједан програм не може да чита из меморије другог програма.

Шта су странице?

Виртуелна меморија је подељена на странице. Свака појединачна страница указује на одређену физичку меморију, може указивати на област у РАМ-у или може указивати на адресу додељену физичком уређају, као што је видео картица.

Већина страница са којима се бавите или упућује на РАМ или се замењују, што значи да су ускладиштене на вашем чврстом диску или ССД-у. Кернел управља физичким изгледом сваке странице. Ако се приступи лажној страници, кернел зауставља нит која покушава да приступи меморији, чита страницу са чврстог диска/ССД-а у РАМ, а затим наставља са извршавањем нити.

Овај процес је транспарентан, што значи да се не чита директно са ХДД/ССД-а. Величина нормалних страница је 4096 бајтова. Величина огромних страница је 2 мегабајта.

Транслацијски асоцијативни бафер (ТЛБ)

Када програм приступи страници меморије, ЦПУ мора знати са које физичке странице да чита податке (то јест, има виртуелну мапу адреса).

Кернел има структуру података (табелу страница) која садржи све информације о страницама које се користе. Користећи ову структуру података, можете мапирати виртуелну адресу у физичку адресу.

Међутим, табела страница је прилично сложена и спора, тако да једноставно не можемо анализирати целу структуру података сваки пут када процес приступа меморији.

На срећу, наш процесор има ТЛБ који кешира мапирање између виртуелних и физичких адреса. То значи да иако треба да рашчланимо табелу страница при првом покушају приступа, сви наредни приступи страници се могу руковати у ТЛБ-у, што омогућава брз рад.

Пошто је имплементиран као физички уређај (што га чини брзим на првом месту), његов капацитет је ограничен. Дакле, ако желите да приступите већем броју страница, ТЛБ неће моћи да ускладишти мапирања за све њих, због чега ће ваш програм радити много спорије.

Хугепагес долази у помоћ

Дакле, шта можемо да урадимо да избегнемо преливање ТЛБ-а? (Претпостављамо да је програму и даље потребна иста количина меморије).

Овде долази Хугепагес. Уместо 4096 бајтова који захтевају само један ТЛБ унос, један ТЛБ унос сада може да указује на огромна 2 мегабајта. Претпоставимо да ТЛБ има 512 уноса, овде без огромних страница можемо да се подударамо:

4096 b⋅512=2 MB

Како онда да се поредимо са њима:

2 MB⋅512=1 GB

Због тога је Хугепагес сјајан. Они могу побољшати продуктивност без много напора. Али овде постоје значајна упозорења.

Огромне лажне странице

Кернел аутоматски прати колико често се користи свака меморијска страница. Ако нема довољно физичке меморије (РАМ), кернел ће преместити мање важне (ређе коришћене) странице на чврсти диск да би ослободио нешто РАМ-а за важније странице.
У принципу, исто важи и за Хугепагес. Међутим, кернел може да мења само целе странице, а не појединачне бајтове.

Рецимо да имамо овакав програм:

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

У овом случају, кернел ће морати да замени (прочита) чак 2 мегабајта информација са чврстог диска/ССД-а само да бисте могли да прочитате један бајт. Што се тиче обичних страница, само 4096 бајтова треба да се прочита са чврстог диска/ССД-а.

Стога, ако је огромна страница замењена, брже је читање само ако треба да приступите целој страници. То значи да ако покушавате да насумично приступите различитим деловима меморије и читате само неколико килобајта, требало би да користите обичне странице и да не бринете ни о чему другом.

С друге стране, ако треба да приступите великом делу меморије узастопно, огромне странице ће побољшати ваше перформансе. Међутим, морате то сами да тестирате (не са апстрактним софтвером) и видите шта ради брже.

Алокација у меморији

Ако пишете Ц, знате да можете захтевати произвољно мале (или скоро произвољно велике) количине меморије из гомиле користећи malloc(). Рецимо да вам треба 30 бајтова меморије:

char* mymemory = malloc(30);

Програмеру може изгледати да „захтевате“ 30 бајтова меморије од оперативног система и враћате показивач на неку виртуелну меморију. Али у ствари malloc () је само Ц функција која позива унутар функције брк и сбрк да затражите или ослободите меморију од оперативног система.

Међутим, захтевати све више меморије за сваку алокацију је неефикасно; највероватније је неки меморијски сегмент већ ослобођен (free()), и можемо га поново користити. malloc() имплементира прилично сложене алгоритме за поновно коришћење ослобођене меморије.

У исто време, све се дешава неприметно за вас, па зашто би вас то забрињавало? Али зато што је изазов free() не значи то меморија се нужно одмах враћа у оперативни систем.

Постоји таква ствар као што је фрагментација меморије. У екстремним случајевима, постоје сегменти хрпе где се користи само неколико бајтова, док је све између ослобођено (free()).

Имајте на уму да је фрагментација меморије невероватно сложена тема, па чак и мање промене програма могу имати значајан утицај. У већини случајева, програми неће изазвати значајну фрагментацију меморије, али треба да будете свесни да ако постоји проблем са фрагментацијом у неком делу гомиле, огромне странице могу погоршати ситуацију.

Селективно коришћење огромних страница

Након што сте прочитали овај чланак, утврдили сте који делови вашег програма могу имати користи од коришћења огромних страница, а који не. Дакле, да ли би огромне странице уопште требало да буду омогућене?

Срећом, можете користити 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(), ова тема има невероватно стрму криву учења. Дакле, ако намеравате да будете заиста добри у томе, припремите се за читање и тестирање неколико недеља пре него што очекујете било какве позитивне резултате.

Шта читати?

Имам једно питање? Напишите у коментарима!

Извор: ввв.хабр.цом

Додај коментар