وڏن صفحن جا فائدا ۽ نقصان

وڏن صفحن جا فائدا ۽ نقصان

ڪورس جي شاگردن لاءِ تيار ڪيل مضمون جو ترجمو "لينڪس ايڊمنسٽريٽر".

اڳي، مون بابت ڳالهايو ته ڪيئن آزمائي ۽ چالو ڪيو لينڪس تي Hugepages.
هي آرٽيڪل صرف مفيد ٿيندو جيڪڏهن توهان وٽ اصل ۾ استعمال ڪرڻ لاءِ جڳهه آهي Hugepages. مون ڪيترن ئي ماڻهن سان ملاقات ڪئي آهي جيڪي بيوقوف بڻيل آهن انهي امڪان سان ته هيج پيجز جادوئي طور تي پيداوار کي بهتر بڻائي سگهندا. بهرحال، وڏي پيجنگ هڪ پيچيده موضوع آهي ۽ ڪارڪردگي کي خراب ڪري سگهي ٿو جيڪڏهن غلط استعمال ڪيو وڃي.

حصو 1: تصديق ڪرڻ ته وڏي صفحا لينڪس تي فعال آهن (اصل هتي)

مسئلو
توهان کي چيڪ ڪرڻ جي ضرورت آهي ته ڇا توهان جي سسٽم تي HugePages فعال آهي.

حل:
اهو تمام سادو آهي:

cat /sys/kernel/mm/transparent_hugepage/enabled

توهان هن وانگر ڪجهه حاصل ڪندا:

always [madvise] never

توھان ڏسندؤ دستياب اختيارن جي ھڪڙي فهرست (هميشه، مهانگو، ڪڏهن به نه)، ۽ في الحال فعال آپشن قوس ۾ بند ڪيو ويندو (ڊفالٽ طور چريو ڪرڻ).

چريو ڪرڻ مطلب ته 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
  • madvise کي ڊفالٽ طور مقرر ڪرڻ لاء، استعمال ڪريو:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

حصو 2: وڏين صفحن جا فائدا ۽ نقصان

اسان ڪوشش ڪنداسين چونڊيل طور تي بيان ڪرڻ جي فائدن، نقصانن ۽ ممڪن نقصانن کي استعمال ڪرڻ جي Hugepages. جيئن ته هڪ ٽيڪنالاجي پيچيده ۽ تدريسي مضمون شايد انهن ماڻهن لاءِ سمجهڻ ڏکيو هوندو جيڪي سوچڻ ۾ ڦاٿل آهن Hugepages هڪ علاج آهي، آئون سادگي لاءِ درستگي کي قربان ڪندس. اهو صرف ذهن ۾ رکڻ جي قابل آهي ته ڪيترائي موضوع واقعي پيچيده آهن ۽ تنهنڪري تمام گهڻو آسان آهن.

مهرباني ڪري نوٽ ڪريو ته اسان لينڪس تي هلندڙ 64-bit x86 سسٽم بابت ڳالهائي رهيا آهيون، ۽ مان صرف اهو سمجهي رهيو آهيان ته سسٽم شفاف وڏن صفحن کي سپورٽ ڪري ٿو (ڇاڪاڻ ته اهو نقصان نه آهي ته وڏي صفحن کي اوور رائٽ نه ڪيو ويو آهي)، جيئن تقريبن ڪنهن به جديد لينڪس ۾ ڪيس آهي. ماحول.

مان هيٺ ڏنل لنڪ ۾ وڌيڪ ٽيڪنيڪل وضاحت شامل ڪندس.

مجازي ياداشت

جيڪڏهن توهان هڪ C++ پروگرامر آهيو، توهان کي خبر آهي ته ميموري ۾ شيون مخصوص ايڊريس (پوائنٽ ويلز) هونديون آهن.

بهرحال، اهي پتا لازمي طور تي جسماني پتي کي ميموري ۾ ظاهر نٿا ڪن (رام ايڊريس). اهي مجازي ياداشت ۾ پتي جي نمائندگي ڪن ٿا. پروسيسر وٽ هڪ خاص ايم ايم يو (ميموري مئنيجمينٽ يونٽ) ماڊل آهي جيڪو ڪرنل ميپ کي ورچوئل ميموري کي فزيڪل مقام تائين پهچائڻ ۾ مدد ڪري ٿو.

ھن طريقي جا ڪيترائي فائدا آھن، پر سڀ کان اھم آھن:

  • ڪارڪردگي (مختلف سببن لاء)؛
  • پروگرام آئسوليشن، يعني ڪو به پروگرام ڪنهن ٻئي پروگرام جي ميموري مان پڙهي نٿو سگهي.

صفحا ڇا آهن؟

مجازي ياداشت صفحن ۾ ورهايل آهي. هر هڪ صفحو هڪ مخصوص فزيڪل ميموري ڏانهن اشارو ڪري ٿو، اهو RAM ۾ ڪنهن علائقي ڏانهن اشارو ڪري سگهي ٿو، يا اهو ڪنهن فزيڪل ڊوائيس تي لڳايو ويو آهي، جهڙوڪ وڊيو ڪارڊ.

گھڻا صفحا جيڪي توھان ڊيل ڪندا آھيو يا ته ريم ڏانھن اشارو ڪندا آھن يا تبديل ٿيل آھن، مطلب ته اھي توھان جي هارڊ ڊرائيو يا SSD تي محفوظ ٿيل آھن. ڪرنل هر صفحي جي جسماني ترتيب کي منظم ڪري ٿو. جيڪڏهن هڪ spoofed پيج تائين رسائي ٿئي ٿي، ڪنيل ٿريڊ کي روڪي ٿو جيڪو ميموري تائين رسائي جي ڪوشش ڪري رهيو آهي، صفحي کي هارڊ ڊرائيو/SSD مان RAM ۾ پڙهي ٿو، ۽ پوءِ ٿريڊ تي عمل جاري رکي ٿو.

اهو عمل وهڪرو شفاف آهي، مطلب ته اهو ضروري ناهي ته سڌو سنئون HDD/SSD مان پڙهي. عام صفحن جي سائيز 4096 بائيٽ آهي. وڏي صفحن جي سائيز 2 ميگا بائيٽ آهي.

ترجمي سان لاڳاپيل بفر (TLB)

جڏهن ڪو پروگرام ميموري جي صفحي تائين پهچندو آهي، سي پي يو کي ڄاڻڻ گهرجي ته ڪهڙي فزيڪل پيج مان ڊيٽا پڙهڻي آهي (يعني هڪ ورچوئل ايڊريس ميپ هجي).

ڪرنل وٽ ڊيٽا جو ڍانچو (صفحو جدول) هوندو آهي جنهن ۾ استعمال ٿيندڙ صفحن بابت سموري معلومات هوندي آهي. هن ڊيٽا جي جوڙجڪ کي استعمال ڪندي، توهان هڪ مجازي پتي کي جسماني پتي تي نقشو ڪري سگهو ٿا.

بهرحال، صفحو جدول ڪافي پيچيده ۽ سست آهي، تنهنڪري اسان هر وقت مڪمل ڊيٽا جي جوڙجڪ جو تجزيو نه ٿا ڪري سگھون جڏهن ڪو پروسيس ميموري تائين رسائي ٿو.

خوشقسمتيءَ سان، اسان جي پروسيسر وٽ هڪ TLB آهي جيڪو ڪيش ڪري ٿو ميپنگ کي ورچوئل ۽ فزيڪل ايڊريس جي وچ ۾. هن جو مطلب اهو آهي ته جيتوڻيڪ اسان کي پهرين رسائي جي ڪوشش تي صفحي جي ٽيبل کي پارس ڪرڻ جي ضرورت آهي، صفحي تائين سڀني بعد ۾ رسائي TLB ۾ هٿ ڪري سگهجي ٿي، تيز آپريشن جي اجازت ڏئي ٿي.

ڇاڪاڻ ته اهو هڪ فزيڪل ڊيوائس جي طور تي لاڳو ڪيو ويو آهي (جيڪو ان کي پهرين جڳهه تي تيز ڪري ٿو)، ان جي گنجائش محدود آهي. تنهن ڪري جيڪڏهن توهان وڌيڪ صفحن تائين رسائي حاصل ڪرڻ چاهيو ٿا، ته TLB انهن سڀني لاءِ ميپنگ اسٽور ڪرڻ جي قابل نه هوندو، جنهن ڪري توهان جو پروگرام تمام گهڻو سست هلندو.

وڏا صفحا بچاء لاء اچي ٿو

پوءِ اسان TLB اوور فلو کان بچڻ لاءِ ڇا ڪري سگهون ٿا؟ (اسان سمجهون ٿا ته پروگرام اڃا تائين ساڳئي مقدار جي ميموري جي ضرورت آهي).

هي آهي جتي وڏيون پيجز اندر اچن ٿيون. 4096 بائيٽ جي بدران صرف هڪ TLB داخل ٿيڻ جي ضرورت آهي، هڪ TLB داخلا هاڻي 2 ميگا بائيٽس ڏانهن اشارو ڪري سگهي ٿي. اچو ته فرض ڪريون TLB وٽ 512 داخلائون آهن، هتي وڏن صفحن کان سواءِ اسان ملائي سگهون ٿا:

4096 b⋅512=2 MB

پوء ڪيئن اسان انهن سان مقابلو ڪري سگهون ٿا:

2 MB⋅512=1 GB

اهو ئي سبب آهي ته Hugepages شاندار آهي. اهي تمام گهڻي ڪوشش کان سواء پيداوار کي بهتر بڻائي سگهن ٿا. پر هتي اهم caveats آهن.

وڏا صفحا اسپفنگ

ڪرنل خودڪار طريقي سان مانيٽر ڪري ٿو ته هر ميموري صفحي کي ڪيترو استعمال ڪيو ويندو آهي. جيڪڏهن ڪافي فزيڪل ميموري (RAM) نه آهي، ڪنيل گهٽ اهم (گهٽ استعمال ٿيل) صفحن کي هارڊ ڊسڪ ڏانهن منتقل ڪندو ته جيئن وڌيڪ اهم صفحن لاءِ ڪجهه RAM خالي ڪري سگهجي.
اصول ۾، ساڳيو ئي لاڳو ٿئي ٿو Hugepages. بهرحال، ڪرنل صرف سڄا صفحا مٽائي سگھي ٿو، انفرادي بائيٽ نه.

اچو ته اسان وٽ هڪ پروگرام هن طرح آهي:

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

انهي حالت ۾، ڪني کي تبديل ڪرڻ جي ضرورت پوندي (پڙهڻ) جيتري معلومات جي 2 ميگا بائيٽ هارڊ ڊرائيو / ايس ايس ڊي مان صرف توهان لاء هڪ بائيٽ پڙهڻ لاء. جيئن ته باقاعده صفحن لاء، صرف 4096 بائيٽ پڙهڻ جي ضرورت آهي هارڊ ڊرائيو / ايس ايس ڊي مان.

تنهن ڪري، جيڪڏهن وڏو صفحو ختم ڪيو ويو آهي، اهو صرف پڙهڻ لاء تيز آهي جيڪڏهن توهان کي پوري صفحي تائين رسائي جي ضرورت آهي. هن جو مطلب اهو آهي ته جيڪڏهن توهان ڪوشش ڪري رهيا آهيو بي ترتيب سان ميموري جي مختلف حصن تائين رسائي ۽ صرف ٻه ڪلوبائٽس پڙهي رهيا آهيو، توهان کي باقاعده صفحا استعمال ڪرڻ گهرجي ۽ ڪنهن ٻئي جي باري ۾ پريشان نه ٿيڻ گهرجي.

ٻئي طرف، جيڪڏهن توهان کي ميموري جي وڏي حصي تائين رسائي حاصل ڪرڻ جي ضرورت آهي ترتيب سان، وڏا صفحا توهان جي ڪارڪردگي کي بهتر بڻائي سگهندا. بهرحال، توهان کي ان کي پاڻ کي جانچڻ جي ضرورت آهي (نه خلاصي سافٽ ويئر سان) ۽ ڏسو ته ڇا ڪم تيزيء سان.

ياداشت ۾ مختص ڪرڻ

جيڪڏهن توهان سي لکندا آهيو، توهان کي خبر آهي ته توهان ڍير مان ميموري جي ذري گهٽ ننڍي (يا تقريبن وڏي) مقدار جي درخواست ڪري سگهو ٿا. malloc(). اچو ته توهان کي 30 بائيٽ ياداشت جي ضرورت آهي:

char* mymemory = malloc(30);

هڪ پروگرامر ڏانهن، اهو ظاهر ٿي سگھي ٿو ته توهان "درخواست" ڪري رهيا آهيو ميموري جي 30 بائيٽ آپريٽنگ سسٽم کان ۽ هڪ پوائنٽر کي ڪجهه ورچوئل ميموري ڏانهن موٽائي رهيا آهيو. پر اصل ۾ malloc () صرف هڪ سي فنڪشن آهي جيڪو فنڪشن جي اندر کان ڪال ڪري ٿو 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

تبصرو شامل ڪريو