විශාල පිටු වල වාසි සහ අවාසි

විශාල පිටු වල වාසි සහ අවාසි

පාඨමාලා සිසුන් සඳහා සකස් කරන ලද ලිපියේ පරිවර්තනය "ලිනක්ස් පරිපාලක".

මීට පෙර, මම ලිනක්ස් හි Hugepages පරීක්ෂා කර සක්‍රීය කරන්නේ කෙසේද යන්න ගැන කතා කළෙමි.
මෙම ලිපිය ප්‍රයෝජනවත් වනුයේ ඔබට සැබවින්ම Hugepages භාවිතා කිරීමට ස්ථානයක් ඇත්නම් පමණි. Hugepages ඵලදායිතාව ඉන්ද්‍රජාලික ලෙස වැඩිදියුණු කරනු ඇතැයි යන අපේක්ෂාවෙන් රැවටෙන බොහෝ පුද්ගලයින් මට හමු වී ඇත. කෙසේ වෙතත්, විශාල පිටුගත කිරීම සංකීර්ණ මාතෘකාවක් වන අතර වැරදි ලෙස භාවිතා කළහොත් කාර්ය සාධනය පිරිහීමට ලක් විය හැක.

1 කොටස: ලිනක්ස් හි විශාල පිටු සක්‍රීය කර ඇති බව තහවුරු කිරීම (මුල් මෙහි)

ගැටලුව:
ඔබගේ පද්ධතියේ HugePages සක්‍රීය කර ඇත්දැයි ඔබ පරීක්ෂා කළ යුතුය.

විසඳුම:
එය ඉතා සරල ය:

cat /sys/kernel/mm/transparent_hugepage/enabled

ඔබට මෙවැනි දෙයක් ලැබෙනු ඇත:

always [madvise] never

පවතින විකල්ප ලැයිස්තුවක් ඔබට පෙනෙනු ඇත (හැම විටම, පිස්සු, කවදාවත්), සහ දැනට සක්‍රිය විකල්පය වරහන් තුළ (පෙරනිමියෙන් madvise).

madvise ඒකේ තේරුම transparent hugepages භාවිතා කරමින් විශාල පිටු පැහැදිලිව ඉල්ලා සිටින මතක ප්‍රදේශ සඳහා පමණක් සක්‍රීය කර ඇත madvise (2).

සැමවිටම ඒකේ තේරුම transparent hugepages සියලුම ක්‍රියාවලි සඳහා සැමවිටම සක්‍රීය කර ඇත. මෙය සාමාන්‍යයෙන් කාර්ය සාධනය වැඩි දියුණු කරයි, නමුත් බොහෝ ක්‍රියාවලීන් කුඩා මතක ප්‍රමාණයක් පරිභෝජනය කරන භාවිත අවස්ථාවක් ඔබට තිබේ නම්, එවිට සමස්ත මතක භාරය නාටකාකාර ලෙස වැඩි විය හැක.

කවදාවත් ඒකේ තේරුම transparent hugepages madvise භාවිතයෙන් ඉල්ලා සිටින විට පවා ඇතුළත් නොවේ. වැඩි විස්තර දැන ගැනීමට, අමතන්න ලියකියවිලි ලිනක්ස් කර්නල්.

පෙරනිමි අගය වෙනස් කරන්නේ කෙසේද

විකල්ප 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 කෝකටත් තෛලයක් ලෙස මුලා වී සිටින මිනිසුන්ට තාක්‍ෂණිකව සංකීර්ණ සහ පාදඩ ලිපියක් තේරුම් ගැනීමට අපහසු වනු ඇති බැවින්, මම සරල බව සඳහා නිරවද්‍යතාවය කැප කරමි. මාතෘකා බොහොමයක් ඇත්ත වශයෙන්ම සංකීර්ණ වන අතර එම නිසා බෙහෙවින් සරල කර ඇති බව මතක තබා ගැනීම වටී.

අප කතා කරන්නේ ලිනක්ස් ධාවනය වන 64-bit x86 පද්ධති ගැන බවත්, ඕනෑම නවීන ලිනක්ස් වල සිදු වන පරිදි, විනිවිද පෙනෙන විශාල පිටු සඳහා (විශාල පිටු නැවත නොලියා තිබීම අවාසියක් නොවන බැවින්) මම සරලව උපකල්පනය කරන්නේ යැයි කරුණාවෙන් සලකන්න. පරිසරය.

මම තවත් තාක්ෂණික විස්තරයක් පහත සබැඳි වලට අමුණමි.

අතථ්‍ය මතකය

ඔබ C++ ක්‍රමලේඛකයෙක් නම්, මතකයේ ඇති වස්තූන්ට නිශ්චිත ලිපින (දර්ශක අගයන්) ඇති බව ඔබ දන්නවා.

කෙසේ වෙතත්, මෙම ලිපින මතකයේ ඇති භෞතික ලිපින (RAM ලිපින) අනිවාර්යයෙන්ම පිළිබිඹු නොකරයි. ඒවා අතථ්‍ය මතකයේ ලිපින නියෝජනය කරයි. ප්‍රොසෙසරයේ විශේෂ MMU (මතක කළමනාකරණ ඒකකය) මොඩියුලයක් ඇත, එය කර්නලයට අතථ්‍ය මතකය භෞතික ස්ථානයකට සිතියම්ගත කිරීමට උපකාරී වේ.

මෙම ප්රවේශය බොහෝ වාසි ඇත, නමුත් වඩාත්ම වැදගත් ඒවා වන්නේ:

  • කාර්ය සාධනය (විවිධ හේතු නිසා);
  • වැඩසටහන් හුදකලා කිරීම, එනම්, වෙනත් වැඩසටහනක මතකයෙන් කිසිදු වැඩසටහනකට කියවිය නොහැක.

පිටු මොනවාද?

අතථ්‍ය මතකය පිටු වලට බෙදා ඇත. සෑම පිටුවක්ම නිශ්චිත භෞතික මතකයකට යොමු කරයි, එය 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) නොමැති නම්, කර්නලය වඩා වැදගත් පිටු සඳහා RAM කිහිපයක් නිදහස් කිරීමට දෘඪ තැටියට අඩු වැදගත් (අඩු නිතර භාවිතා වන) පිටු ගෙන යයි.
ප්‍රතිපත්තිමය වශයෙන්, Hugepages සඳහා ද එය අදාළ වේ. කෙසේ වෙතත්, කර්නලයට මාරු කළ හැක්කේ සම්පූර්ණ පිටු පමණක් මිස තනි බයිට් නොවේ.

අපි හිතමු අපිට මේ වගේ වැඩසටහනක් තියෙනවා කියලා.

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

මෙම අවස්ථාවේදී, කර්නලය ඔබට එක් බයිටයක් කියවීම සඳහා දෘඪ තැටියේ/එස්එස්ඩී වෙතින් මෙගාබයිට් 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

අදහස් එක් කරන්න