د لوی پاڼو ګټې او زیانونه

د لوی پاڼو ګټې او زیانونه

د کورس زده کونکو لپاره چمتو شوي مقالې ژباړه "د لینکس مدیر".

مخکې، ما په لینوکس کې د Hugepages ازموینې او فعالولو څرنګوالي په اړه خبرې وکړې.
دا مقاله به یوازې هغه وخت ګټوره وي که تاسو واقعیا د هګپاج کارولو لپاره ځای ولرئ. ما د ډیرو خلکو سره لیدلي دي چې د دې احتمال په واسطه احمق شوي چې لوی پاڼې به په جادویی توګه د محصولاتو وده وکړي. په هرصورت، لوی پاڼه کول یوه پیچلې موضوع ده او کولی شي فعالیت خراب کړي که چیرې په غلط ډول وکارول شي.

برخه 1: تایید کول چې لوی پاڼې په لینکس کې فعال شوي دي (اصلي دلته)

ستونزه:
تاسو اړتیا لرئ وګورئ چې آیا ستاسو په سیسټم کې HugePages فعال شوي دي.

د حل لاره:
دا خورا ساده دی:

cat /sys/kernel/mm/transparent_hugepage/enabled

تاسو به د دې په څیر یو څه ترلاسه کړئ:

always [madvise] never

تاسو به د شته اختیارونو لیست وګورئ (تل، لیوالتیا، هیڅکله)، او اوس مهال فعال انتخاب به په قوسونو کې تړلی وي (د ډیفالټ په واسطه madvise).

madvise پدې معنی چې transparent hugepages یوازې د حافظې ساحو لپاره فعال شوي چې په ښکاره ډول د لوی پاڼو کارولو غوښتنه کوي مینه (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
  • د ډیفالټ په توګه د مدویز تنظیم کولو لپاره ، وکاروئ:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

دویمه برخه: د لوی پاڼو ګټې او زیانونه

موږ به هڅه وکړو چې په انتخابي ډول د هیجپایج کارولو ګټې ، زیانونه او احتمالي زیانونه تشریح کړو. څرنګه چې د ټیکنالوژیک پلوه پیچلي او پیډانټیک مقاله به د هغو خلکو لپاره پوهیدل ستونزمن وي چې فکر کوي د هیج پیجز یوه درملنه ده ، زه به د سادګۍ لپاره دقت قرباني کړم. دا یوازې په پام کې نیولو سره ارزښت لري چې ډیری موضوعات واقعیا پیچلي دي او له همدې امله خورا ساده شوي.

مهرباني وکړئ په یاد ولرئ چې موږ د 64-bit x86 سیسټمونو په اړه خبرې کوو چې لینکس چلوي، او دا چې زه په ساده ډول داسې انګیرم چې سیسټم د شفاف لوی پاڼو ملاتړ کوي (ځکه چې دا یو زیان نه دی چې لوی پاڼې نه لیکل کیږي)، لکه څنګه چې په هر عصري لینکس کې قضیه ده چاپیریال

زه به په لاندې لینکونو کې نور تخنیکي توضیحات ضمیمه کړم.

مجازی حافظه

که تاسو د C++ پروګرامر یاست، تاسو پوهیږئ چې په حافظه کې شیان ځانګړي پتې لري (د پوائنټر ارزښتونه).

په هرصورت، دا پتې په حافظه کې فزیکي پتې نه منعکس کوي (RAM پتې). دوی په مجازی حافظه کې پتې استازیتوب کوي. پروسیسر یو ځانګړی MMU (د حافظې مدیریت واحد) ماډل لري چې د کرنل نقشه مجازی حافظې سره فزیکي موقعیت کې مرسته کوي.

دا طریقه ډیری ګټې لري، مګر ترټولو مهم یې دا دي:

  • فعالیت (د مختلفو دلیلونو لپاره)؛
  • د پروګرام جلا کول، دا دی، هیڅ پروګرام نشي کولی د بل پروګرام له حافظې څخه لوستل شي.

پاڼې څه دي؟

مجازی حافظه په پاڼو ویشل شوې ده. هره انفرادي پاڼه یو ځانګړي فزیکي حافظې ته اشاره کوي، دا کولی شي په RAM کې یوې سیمې ته اشاره وکړي، یا دا کولی شي د فزیکي وسیلو لپاره ټاکل شوي پته ته اشاره وکړي، لکه د ویډیو کارت.

ډیری هغه پاڼې چې تاسو ورسره معامله کوئ یا هم رام ته اشاره کوي یا بدل شوي، پدې معنی چې دوی ستاسو په هارډ ډرایو یا SSD کې زیرمه شوي. کرنل د هرې پاڼې فزیکي ترتیب اداره کوي. که چیرې سپوفي پاڼې ته لاسرسی ومومي، کرنل هغه تار ودروي چې حافظې ته د لاسرسي هڅه کوي، پاڼه د هارډ ډرایو/SSD څخه رام ته لولي، او بیا د تار اجرا کولو ته دوام ورکوي.

دا پروسه شفافه ده، پدې معنی چې دا په مستقیم ډول د HDD/SSD څخه نه لوستل کیږي. د نورمال پاڼو اندازه 4096 بایټه ده. د لوی مخونو اندازه 2 میګابایټ ده.

د ژباړې شریک بفر (TLB)

کله چې یو برنامه د حافظې یوې پاڼې ته لاسرسی ومومي، CPU باید پوه شي چې کوم فزیکي پاڼه به د معلوماتو لوستلو لپاره وي (یعنې د مجازی پتې نقشه ولري).

کرنل د معلوماتو جوړښت (د مخ جدول) لري چې د هغه پاڼو په اړه ټول معلومات لري چې کارول کیږي. د دې ډاټا جوړښت په کارولو سره، تاسو کولی شئ یو مجازی پته فزیکي پته ته نقشه کړئ.

په هرصورت، د پاڼې میز خورا پیچلی او ورو دی، نو موږ په ساده ډول نشو کولی د ټول ډیټا جوړښت تحلیل کړو هرکله چې پروسه حافظې ته لاسرسی ومومي.

خوشبختانه، زموږ پروسیسر یو TLB لري چې د مجازی او فزیکي ادرسونو تر مینځ نقشه کیچ کوي. دا پدې مانا ده چې که څه هم موږ اړتیا لرو د لومړي لاسرسي په هڅه کې د پا pageې میز تجزیه کړو ، پا pageې ته ټول وروستي لاسرسي په TLB کې اداره کیدی شي ، د ګړندي عملیاتو لپاره اجازه ورکوي.

ځکه چې دا د فزیکي وسیلې په توګه پلي کیږي (کوم چې دا په لومړي ځای کې ګړندی کوي) ، د دې ظرفیت محدود دی. نو که تاسو غواړئ ډیرو پاڼو ته لاسرسی ومومئ، TLB به ونه شي کولی د ټولو لپاره نقشه ذخیره کړي، چې ستاسو برنامه خورا ورو پرمخ ځي.

لوی پاڼې د ژغورنې لپاره راځي

نو موږ د TLB د زیاتیدو مخنیوي لپاره څه کولی شو؟ (موږ فکر کوو چې برنامه لاهم ورته حافظې ته اړتیا لري).

دا هغه ځای دی چې لوی پاڼې راځي. د 4096 بایټونو پرځای چې یوازې یو TLB ننوتلو ته اړتیا لري، د 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 میګابایټ معلوماتو بدلولو (لوستلو) ته اړتیا ولري. لکه څنګه چې د منظمو پاڼو لپاره، یوازې 4096 بایټ د هارډ ډرایو/SSD څخه لوستلو ته اړتیا لري.

له همدې امله، که لوی پاڼه له پامه غورځول شي، دا یوازې د لوستلو لپاره ګړندی دی که تاسو اړتیا لرئ ټولې پاڼې ته لاسرسی ومومئ. دا پدې مانا ده چې که تاسو په تصادفي ډول د حافظې مختلف برخو ته د لاسرسي هڅه کوئ او یوازې یو څو کیلوبایټ لوستل کوئ نو تاسو باید منظم پا pagesې وکاروئ او د بل څه په اړه اندیښنه مه کوئ.

له بلې خوا، که تاسو په ترتیب سره د حافظې لویې برخې ته لاسرسی ته اړتیا لرئ، لوی پاڼې به ستاسو فعالیت ښه کړي. په هرصورت ، تاسو اړتیا لرئ دا پخپله و ازموئ (نه د خلاصې سافټویر سره) او وګورئ چې څه ګړندي کار کوي.

په حافظه کې تخصیص

که تاسو 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

Add a comment