Mga Kalamangan at Kahinaan ng HugePages

Mga Kalamangan at Kahinaan ng HugePages

Pagsasalin ng artikulong inihanda para sa mga mag-aaral ng kurso "Linux Administrator".

Dati, napag-usapan ko kung paano subukan at paganahin ang Hugepages sa Linux.
Magiging kapaki-pakinabang lang ang artikulong ito kung mayroon ka talagang lugar para magamit ang Hugepages. Marami na akong nakilalang tao na naloloko sa pag-asam na ang Hugepages ay mahiwagang mapapabuti ang pagiging produktibo. Gayunpaman, ang hugepaging ay isang kumplikadong paksa at maaaring pababain ang pagganap kung ginamit nang hindi tama.

Bahagi 1: Pagpapatunay na ang mga malalaking pahina ay pinagana sa Linux (orihinal dito)

Problema:
Kailangan mong suriin kung pinagana ang HugePages sa iyong system.

solusyon:
Ito ay medyo simple:

cat /sys/kernel/mm/transparent_hugepage/enabled

Makakakuha ka ng ganito:

always [madvise] never

Makakakita ka ng listahan ng mga available na opsyon (lagi, madvise, never), at ang kasalukuyang aktibong opsyon ay ilalagay sa panaklong (bilang default madvise).

madvise ibig sabihin nun transparent hugepages pinagana lamang para sa mga lugar ng memorya na tahasang humihiling ng malalaking pahina na gumagamit madvise(2).

palagi ibig sabihin nun transparent hugepages palaging pinagana para sa lahat ng mga proseso. Karaniwang pinapabuti nito ang pagganap, ngunit kung mayroon kang kaso ng paggamit kung saan maraming proseso ang kumukonsumo ng kaunting memorya, maaaring tumaas nang husto ang kabuuang pag-load ng memorya.

hindi kailanman ibig sabihin nun transparent hugepages hindi isasama kahit na hiniling gamit ang madvise. Upang malaman ang higit pa, makipag-ugnayan dokumentasyon Mga kernel ng Linux.

Paano baguhin ang default na halaga

Pagpipilian 1: Direktang palitan sysfs (pagkatapos i-reboot ang parameter ay babalik sa default na halaga nito):

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

Pagpipilian 2: Baguhin ang default ng system sa pamamagitan ng muling pag-compile ng kernel na may binagong configuration (inirerekumenda lang ang opsyong ito kung gumagamit ka ng custom na kernel):

  • Upang palaging itakda bilang default, gamitin ang:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • Upang itakda ang madvise bilang default, gamitin ang:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

Bahagi 2: Mga Kalamangan at Kahinaan ng HugePages

Susubukan naming piliing ipaliwanag ang mga pakinabang, disadvantages at posibleng mga pitfalls ng paggamit ng Hugepages. Dahil ang isang teknolohikal na kumplikado at pedantic na artikulo ay malamang na mahirap unawain para sa mga taong nalinlang sa pag-iisip na ang Hugepages ay isang panlunas sa lahat, isasakripisyo ko ang katumpakan para sa pagiging simple. Nararapat lamang na tandaan na marami sa mga paksa ay talagang kumplikado at samakatuwid ay lubos na pinasimple.

Pakitandaan na pinag-uusapan natin ang tungkol sa mga 64-bit x86 system na nagpapatakbo ng Linux, at ipinapalagay ko lang na sinusuportahan ng system ang mga transparent na malalaking pahina (dahil hindi isang disadvantage na hindi na-overwrite ang mga malalaking pahina), tulad ng kaso sa halos anumang modernong Linux. kapaligiran.

Maglalagay ako ng higit pang teknikal na paglalarawan sa mga link sa ibaba.

Virtual na memorya

Kung ikaw ay isang C++ programmer, alam mo na ang mga bagay sa memorya ay may mga tiyak na address (mga pointer value).

Gayunpaman, ang mga address na ito ay hindi kinakailangang sumasalamin sa mga pisikal na address sa memorya (mga RAM address). Kinakatawan nila ang mga address sa virtual memory. Ang processor ay may espesyal na MMU (memory management unit) na module na tumutulong sa kernel na mag-map ng virtual memory sa isang pisikal na lokasyon.

Ang pamamaraang ito ay may maraming mga pakinabang, ngunit ang pinakamahalaga ay:

  • Pagganap (para sa iba't ibang dahilan);
  • Programa isolation, ibig sabihin, walang program ang makakabasa mula sa memorya ng isa pang program.

Ano ang mga pahina?

Ang virtual memory ay nahahati sa mga pahina. Ang bawat indibidwal na pahina ay tumuturo sa isang partikular na pisikal na memorya, maaari itong tumuro sa isang lugar sa RAM, o maaari itong tumuro sa isang address na nakatalaga sa isang pisikal na device, tulad ng isang video card.

Karamihan sa mga page na iyong haharapin ay tumuturo sa RAM o napalitan, ibig sabihin ay nakaimbak ang mga ito sa iyong hard drive o SSD. Pinamamahalaan ng kernel ang pisikal na layout ng bawat pahina. Kung ma-access ang isang spoofed page, ihihinto ng kernel ang thread na sinusubukang i-access ang memory, babasahin ang page mula sa hard drive/SSD papunta sa RAM, at pagkatapos ay magpapatuloy sa pagpapatupad ng thread.

Ang prosesong ito ay stream transparent, ibig sabihin ay hindi ito kinakailangang direktang basahin mula sa HDD/SSD. Ang laki ng mga normal na pahina ay 4096 bytes. Ang laki ng Hugepage ay 2 megabytes.

Translation-associative buffer (TLB)

Kapag ang isang programa ay nag-access ng isang pahina ng memorya, ang CPU ay dapat malaman kung aling pisikal na pahina ang magbabasa ng data (iyon ay, may isang virtual na mapa ng address).

Ang kernel ay may istraktura ng data (talahanayan ng pahina) na naglalaman ng lahat ng impormasyon tungkol sa mga pahinang ginagamit. Gamit ang istruktura ng data na ito, maaari mong imapa ang isang virtual na address sa isang pisikal na address.

Gayunpaman, ang talahanayan ng pahina ay medyo kumplikado at mabagal, kaya't hindi namin masuri ang buong istraktura ng data sa tuwing ang isang proseso ay nag-a-access ng memorya.

Sa kabutihang palad, ang aming processor ay may TLB na nag-cache ng pagmamapa sa pagitan ng virtual at pisikal na mga address. Nangangahulugan ito na bagama't kailangan nating i-parse ang talahanayan ng pahina sa unang pagtatangka sa pag-access, ang lahat ng kasunod na pag-access sa pahina ay maaaring pangasiwaan sa TLB, na nagbibigay-daan para sa mabilis na operasyon.

Dahil ito ay ipinatupad bilang isang pisikal na aparato (na ginagawang mabilis sa unang lugar), ang kapasidad nito ay limitado. Kaya't kung gusto mong mag-access ng higit pang mga pahina, hindi makakapag-imbak ang TLB ng mga pagmamapa para sa lahat ng mga ito, na nagiging sanhi ng mas mabagal na pagtakbo ng iyong programa.

Ang mga Hugpage ay sumagip

Kaya ano ang maaari nating gawin upang maiwasan ang pag-apaw ng TLB? (Ipagpalagay namin na ang programa ay nangangailangan pa rin ng parehong dami ng memorya).

Dito pumapasok ang Hugepages. Sa halip na 4096 bytes na nangangailangan lamang ng isang TLB entry, ang isang TLB entry ay maaari na ngayong tumuro sa napakalaking 2 megabytes. Ipagpalagay natin na ang TLB ay mayroong 512 entries, dito kung walang Hugepages ay maaari nating itugma:

4096 bβ‹…512=2 MB

Kung gayon, paano natin maihahambing sa kanila:

2 MBβ‹…512=1 GB

Ito ang dahilan kung bakit kahanga-hanga ang Hugepages. Mapapabuti nila ang pagiging produktibo nang walang labis na pagsisikap. Ngunit may mga makabuluhang caveat dito.

Hugepages spoofing

Awtomatikong sinusubaybayan ng kernel kung gaano kadalas ginagamit ang bawat pahina ng memorya. Kung walang sapat na pisikal na memorya (RAM), ililipat ng kernel ang hindi gaanong mahalaga (hindi gaanong madalas gamitin) na mga pahina sa hard disk upang palayain ang ilang RAM para sa mas mahalagang mga pahina.
Sa prinsipyo, ang parehong naaangkop sa Hugepages. Gayunpaman, ang kernel ay maaari lamang magpalit ng buong mga pahina, hindi mga indibidwal na byte.

Sabihin nating mayroon tayong programang tulad nito:

char* mymemory = malloc(2*1024*1024); // Π’ΠΎΠ·ΡŒΠΌΠ΅ΠΌ это Π·Π° ΠΎΠ΄Π½Ρƒ Hugepage!
// Π—Π°ΠΏΠΎΠ»Π½ΠΈΠΌ mymemory ΠΊΠ°ΠΊΠΈΠΌΠΈ-Π»ΠΈΠ±ΠΎ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ
// Π‘Π΄Π΅Π»Π°Π΅ΠΌ ΠΌΠ½ΠΎΠ³ΠΎ Π΄Ρ€ΡƒΠ³ΠΈΡ… Π²Π΅Ρ‰Π΅ΠΉ,
// ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄ΡƒΡ‚ ΠΊ ΠΏΠΎΠ΄ΠΌΠ΅Π½Π΅ страницы mymemory
// ...
// Запросим доступ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊ ΠΏΠ΅Ρ€Π²ΠΎΠΌΡƒ Π±Π°ΠΉΡ‚Ρƒ
putchar(mymemory[0]); 

Sa kasong ito, kakailanganin ng kernel na palitan (basahin) ang hanggang 2 megabytes ng impormasyon mula sa hard drive/SSD para lang makapagbasa ka ng isang byte. Tulad ng para sa mga regular na pahina, 4096 bytes lamang ang kailangang basahin mula sa hard drive/SSD.

Samakatuwid, kung ma-override ang hugepage, mas mabilis lang itong basahin kung kailangan mong i-access ang buong page. Nangangahulugan ito na kung sinusubukan mong random na ma-access ang iba't ibang bahagi ng memorya at nagbabasa lamang ng ilang kilobytes, dapat kang gumamit ng mga regular na pahina at huwag mag-alala tungkol sa anumang bagay.

Sa kabilang banda, kung kailangan mong i-access ang malaking bahagi ng memory nang sunud-sunod, mapapabuti ng malalaking pahina ang iyong pagganap. Gayunpaman, kailangan mong subukan ito mismo (hindi gamit ang abstract software) at tingnan kung ano ang mas mabilis na gumagana.

Paglalaan sa memorya

Kung isusulat mo ang C, alam mo na maaari kang humiling ng arbitraryong maliit (o halos arbitraryong malaki) na halaga ng memorya mula sa heap gamit ang malloc(). Sabihin nating kailangan mo ng 30 bytes ng memorya:

char* mymemory = malloc(30);

Sa isang programmer, maaaring lumitaw na ikaw ay "humihiling" ng 30 bytes ng memorya mula sa operating system at nagbabalik ng isang pointer sa ilang virtual memory. Pero sa totoo lang malloc () ay isang C function lamang na tumatawag mula sa loob ng function brk at sbrk upang humiling o magbakante ng memorya mula sa operating system.

Gayunpaman, ang paghiling ng higit at higit na memorya para sa bawat alokasyon ay hindi epektibo; malamang na ang ilang bahagi ng memorya ay napalaya na (free()), at magagamit natin itong muli. malloc() nagpapatupad ng medyo kumplikadong mga algorithm para sa muling paggamit ng napalaya na memorya.

Kasabay nito, ang lahat ay nangyayari nang hindi napapansin para sa iyo, kaya bakit ito mag-aalala sa iyo? Pero dahil ang hamon free() hindi ibig sabihin nun ang memorya ay kinakailangang ibalik kaagad sa operating system.

Mayroong isang bagay tulad ng memory fragmentation. Sa matinding mga kaso, may mga heap segment kung saan ilang byte lang ang ginagamit, habang lahat ng nasa pagitan ay na-freeze. (free()).

Pakitandaan na ang memory fragmentation ay isang hindi kapani-paniwalang kumplikadong paksa, at kahit na ang maliliit na pagbabago sa isang programa ay maaaring magkaroon ng malaking epekto. Sa karamihan ng mga kaso, ang mga programa ay hindi magiging sanhi ng makabuluhang pagkapira-piraso ng memorya, ngunit dapat mong malaman na kung may problema sa pagkapira-piraso sa ilang lugar ng heap, ang malalaking pahina ay maaaring magpalala ng sitwasyon.

Piliing paggamit ng malalaking pahina

Matapos basahin ang artikulo, natukoy mo kung aling mga bahagi ng iyong programa ang maaaring makinabang mula sa paggamit ng mga malalaking pahina at alin ang hindi. Kaya dapat bang paganahin ang mga malalaking pahina?

Sa kabutihang palad ay magagamit mo madvise()upang paganahin ang hugepaging para lamang sa mga lugar ng memorya kung saan ito ay magiging kapaki-pakinabang.

Una, suriin kung ang mga hugepage ay tumatakbo sa madvise() mode gamit tagubilin sa simula ng artikulo.

Pagkatapos, gamitin madvise()upang sabihin sa kernel nang eksakto kung saan gagamitin ang mga malalaking pahina.

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

Tandaan na ang pamamaraang ito ay payo lamang sa kernel kung paano pamahalaan ang memorya. Hindi ito nangangahulugan na ang kernel ay awtomatikong gagamit ng malalaking pahina para sa isang naibigay na memorya.

Sumangguni sa dokumentasyon (manpage)madviseupang matuto nang higit pa tungkol sa pamamahala ng memorya at madvise(), ang paksang ito ay may hindi kapani-paniwalang matarik na kurba ng pagkatuto. Kaya't kung balak mong maging mahusay dito, maghanda na magbasa at magsubok sa loob ng ilang linggo bago ka umasa ng anumang positibong resulta.

Ano ang dapat basahin?

May tanong? Sumulat sa mga komento!

Pinagmulan: www.habr.com

Magdagdag ng komento