درک اندازه صفحات حافظه در Arm64

یکی از راه هایی که معماری Arm64 با x86 متفاوت است، امکان پیکربندی اندازه صفحات حافظه در واحد مدیریت حافظه (MMU) CPU به 4K، 16K یا 64K است. این مقاله به طور خلاصه بیان میکند که اندازه صفحه حافظه چیست، چگونه اندازه صفحه را در سیستمهای لینوکس پیکربندی کنیم، و چه زمانی ممکن است استفاده از اندازه صفحه متفاوت در برنامههای خود منطقی باشد.
مقدمه ای بر اندازه صفحه حافظه
همانطور که قبلا در تشخیص و رفع مشکل عملکرد خطای صفحه با Arm64 Atomics بحث کردیم، سیستم عامل ها فضای آدرس حافظه مجازی را به برنامه ها ارائه می دهند و صفحات حافظه فیزیکی را با استفاده از جدول صفحه به آدرس های حافظه مجازی نگاشت می کنند. سپس CPU مکانیزمی به نام Translation Lookaside Buffer (TLB) ارائه میکند تا اطمینان حاصل کند که صفحات حافظه اخیراً دسترسی به آنها را میتوان با استفاده از حافظه نهان CPU L1 یا L2 سریعتر شناسایی کرد و خواند.
اندازه صفحات حافظه فیزیکی (به نام گرانول) در معماری x86 4 کیلوبایت ثابت است. با این حال، در سیستمهای ARM64 مانند Ampere Altra(R) یا AmpereOne(R)، توسعهدهنده میتواند اندازه صفحات حافظه فیزیکی را روی 4KB، 16KB یا 64KB پیکربندی کند.
چه زمانی از صفحات بزرگتر استفاده کنیم؟
از آنجایی که تغییر اندازه صفحه می تواند بر کارایی حافظه و عملکرد سیستم شما تأثیر بگذارد، مهم است که درک کنید که چه زمانی منطقی است که از اندازه صفحه بزرگتر استفاده کنید و معاوضه های مربوط به آن. اندازه صفحات بزرگتر می تواند با داشتن صفحاتی که پر نیستند منجر به استفاده کمتر کارآمد از حافظه شود.
به عنوان مثال، اگر ما 7 کیلوبایت داده را در حافظه ذخیره کنیم، در سیستمی با صفحات هسته 4 کیلوبایتی، از دو صفحه 4 کیلوبایتی برای مجموع 8 کیلوبایت حافظه استفاده می شود که بازده 87.5٪ است. با این حال، در سیستمی با صفحات 64 کیلوبایت، ما اکنون یک صفحه 64 کیلوبایتی با 7 کیلوبایت داده را برای بازدهی 11% با تخصیص واحد بالا مصرف می کنیم.
با این حال، MMU و هسته سیستم عامل به اندازه کافی هوشمند هستند تا از بلوک های به هم پیوسته حافظه استفاده کنند که قبلاً تخصیص داده شده اند اما برای تخصیص حافظه آینده پر نیستند. اگر همین فرآیند بعداً 32 کیلوبایت حافظه اختصاص دهد، ما هنوز فقط از یک صفحه 64 کیلوبایتی با 39 کیلوبایت اشغال شده استفاده می کنیم. با اندازه صفحه 4K، اکنون ده صفحه 4 کیلوبایتی را مدیریت خواهیم کرد.
مبادله دوم در عملکرد به دلیل از دست رفتن حافظه پنهان برای جستجوی جدول صفحه است. تعداد نسبتاً کمی از ورودی های صفحه در TLB برای هر سطح حافظه پنهان (L1، L2، حافظه پنهان سطح سیستم) ذخیره می شود.
با اندازه صفحات بزرگتر، این ورودی های TLB مقدار بیشتری از حافظه فیزیکی را پوشش می دهند. برای مثال در پردازنده های Ampere Altra و Altra Max، L1 data TLB دارای 48 ورودی و L2 TLB دارای 1280 ورودی است.
این بدان معناست که با یک گرانول 4 کیلوبایتی، L1 TLB میتواند آدرسها را برای 192 کیلوبایت حافظه فیزیکی ذخیره کند، و L2 TLB میتواند آدرسهای صفحهای را که 5 مگابایت حافظه فیزیکی را پوشش میدهند، ذخیره کند.
با اندازه صفحه 64 کیلوبایت، این اندازه برای L1 داده TLB به 3MB و برای L2 TLB به 80MB افزایش می یابد. هر فقدان حافظه پنهان در TLB زمان را برای پیاده روی در صفحه اضافه می کند تا صفحه فیزیکی مطابق با جستجوی حافظه مجازی را پیدا کند، صفحه را پس از یافتن در حافظه پنهان ذخیره کند و TLB را به طور مناسب به روز کند. با صفحات بزرگتر، از دست رفتن حافظه پنهان کمتر و عملکرد بهتری برای بارهای کاری فشرده خواهید داشت.
همچنین با داشتن مناطق بزرگتر از حافظه پیوسته در دسترس، عملکرد I/O را بهبود می بخشید. در نتیجه، برنامه های کاربردی داده فشرده که داده های زیادی در حافظه یا در حال انتقال دارند، می توانند از اندازه صفحه بزرگتر بهره مند شوند. برخی از این کاربردها عبارتند از:
پایگاههای داده: سیستمهای پایگاه داده تمایل زیادی به ذخیره اطلاعات زیادی در حافظه برای اهداف کش دارند و ورودی/خروجی دیسک زیادی برای مجموعه دادههای بزرگ دارند. هر دو ویژگی سرورهای پایگاه داده را کاندیدای عالی برای اندازه صفحات حافظه بزرگ می کند.
زیرساخت مجازی سازی: ماشین های مجازی (VM) شامل یک تصویر دیسک است که از یک هسته سیستم عامل و تمام برنامه های کاربردی مورد نیاز آن ماشین مجازی تشکیل شده است و اندازه آنها از صدها مگابایت تا صدها گیگابایت است. در نتیجه، آنها می توانند از مقدار زیادی حافظه استفاده کنند و می توانند از اندازه صفحات بزرگتر بهره مند شوند.
ساخت سرور برای ادغام مداوم: کارهایی مانند ساخت هسته لینوکس هزاران فایل منبع را پردازش می کند و در حین کامپایل کردن آنها از رم زیادی استفاده می کند. به عنوان یک بار کاری بالا، میزبان هایی که با اندازه صفحه بزرگتر پیکربندی شده اند به عنوان سرورهای ساخت بهتر عمل می کنند.
برنامههای سنگین شبکه یا ورودی/خروجی: برای برنامههایی با تعداد زیادی ورودی/خروجی شبکه و پردازش دادههای درون حافظه مانند کش اشیاء، متعادلکنندههای بار، فایروالها یا جریان ویدیو، صفحات حافظه بزرگ میتوانند منجر به خطاهای صفحه کمتر و بهبود عملکرد شوند.
برنامه های کاربردی فشرده حافظه مانند AI Inference: AI Inference، اجرای یک مدل آموزش دیده مانند موتور توصیه یک ربات چت LLM، یک حجم کاری فشرده حافظه و CPU است که در آن اندازه صفحه حافظه بزرگ می تواند به ارائه عملکرد بالا کمک کند.
به طور کلی، عملکرد این نوع برنامه ها با اندازه صفحه بزرگتر به عوامل مختلفی از جمله مجموعه داده های درگیر و الگوی دسترسی به حافظه برنامه بستگی دارد.
اگر فکر می کنید که برنامه شما می تواند از صفحات حافظه بزرگتر بهره مند شود، باید حجم کاری مورد نظر خود را با صفحات 4K و 64K محک بزنید و بر اساس نتایج آزمایشات خود تصمیم به استقرار خود را بگیرید.
علاوه بر محک زدن برنامه مورد نظر خود با صفحات 4K و 64K با استفاده از دادههای سبک تولید، میتوانید با استفاده از ابزار «perf»، با اندازهگیری Stallهای TLB، مزیت بالقوه اندازههای صفحه بزرگتر را ارزیابی کنید (یعنی تعداد دفعاتی که از دست دادن TLB منجر به توقف خط لوله CPU میشود در حالی که منتظر بارگذاری اطلاعات از حافظه هستید).
ابتدا بررسی کنید که هسته از شمارندههای stall TLB در AmpereONE و CPUهای جدیدتر پشتیبانی میکند.
# perf list | grep end_tlb stall_backend_tlb stall_frontend_tlbبا پشتیبانی هسته تایید شده، توقف خط لوله به دلیل از دست دادن TLB قابل اندازه گیری است:
# perf stat -e instructions,cycles,stall_frontend_tlb,stall_backend_tlb ./a.out time for 12344321 * 100M nops: 3.7 s Performance counter stats for './a.out': 12,648,071,049 instructions # 1.14 insn per cycle 11,109,161,102 cycles 1,482,795,078 stall_frontend_tlb 1,334,751 stall_backend_tlb 3\. 706937365 seconds time elapsed 3\. 629966000 seconds user 0\. 000995000 seconds sysنسبت (stall_frontend_tlb + stall_backend_tlb)/چرخهها حد بالایی برای زمانی است که میتوان با استفاده از صفحات حافظه بزرگتر ذخیره کرد.
اما مراقب باشید که از آنجایی که 4K برای مدت طولانی اندازه صفحه پیشفرض بوده است، برخی از بستههای نرمافزاری ممکن است این فرض را در مورد سیستم شما ایجاد کنند که منجر به کارایی پایین در استفاده از حافظه میشود. این یک وضعیت معمولی در پشتههای نرمافزار مدرن نیست، اما توصیه میشود قبل از انجام اندازههای صفحه بزرگتر، مقداری آزمایش و محکگذاری انجام دهید.
پیکربندی اندازه صفحات بزرگتر در CPUهای Ampere
تغییر اندازه اندازه صفحه حافظه نیازمند اجرای یک هسته سیستم عامل است که برای پشتیبانی از اندازه دلخواه شما کامپایل شده است. برای سیستمعاملهای ابری محبوب مانند Red Hat Enterprise Linux، Oracle Enterprise Linux، Suse Enterprise Linux یا Ubuntu Canonical، این سیستمعاملها با هستههای از پیش ساختهشدهای عرضه میشوند که از اندازه صفحه ۴ کیلوبایت و اندازه صفحه ۶۴ کیلوبایت در Arm64 پشتیبانی میکنند.
برای استفاده از یک هسته با صفحات 64 کیلوبایتی در Red Hat Enterprise Linux 9:
1. بسته kernel-64k را نصب کنید:
dnf –y install kernel-64k2. برای فعال کردن هسته 64K به طور پیش فرض در زمان بوت شدن:
k=$(echo /boot/vmlinuz*64k) grubby --set-default=$k \ --update-kernel=$k \ --args="crashkernel=2G-:640M"برای بوت کردن یک هسته 64 کیلوبایتی در اوبونتو 22.04:
1. ISO arm64+largemem را که به طور پیش فرض حاوی هسته 64K است نصب کنید، یا:
2. بسته linux-generic-64k را نصب کنید که با دستور sudo apt install linux-generic-64K یک گزینه هسته 64K به منوی بوت اضافه می کند.
3. می توانید با به روز رسانی منوی بوت grub2 با دستور زیر، هسته 64K را به عنوان گزینه بوت پیش فرض تنظیم کنید:
echo "GRUB_FLAVOUR_ORDER=generic-64k" | sudo tee /etc/ default /grub.d/local-order.cfgبرای صفحات 64 کیلوبایتی در اوراکل لینوکس:
1. بسته kernel-uek64k را نصب کنید:
sudo dnf install -y kernel-uek64k2. هسته 64K را به عنوان پیش فرض در زمان بوت تنظیم کنید:
sudo grubby --set-default=$(echo /boot/vmlinuz*64k)3. پس از راه اندازی مجدد سیستم، می توانید تأیید کنید که هسته 64K را با استفاده از getconf اجرا می کنید همانطور که در زیر توضیح داده شده است.
دستورالعمل های مشابه ممکن است در وب سایت های سایر توزیع های سیستم عامل موجود باشد.
اگر هسته لینوکس خود را می سازید، می توانید از make menuconfig برای تغییر پیکربندی هسته استفاده کنید. در زیر منوی «نوع و ویژگیهای پردازنده»، ثبتهای ویژگی CPU ARM64 را بر اساس گزینه پیکربندی ویژگیهای هسته پیدا میکنید که میتوانید آن را به 16K یا 64K تغییر دهید.
همچنین، میتوانید فایل پیکربندی هسته .config را مستقیماً تغییر دهید تا مقدار CONFIG_ARM_PAGE_SHIFT را از مقدار پیشفرض 12 (4K = 212 بایت) به 14 (16K = 214 بایت) یا 16 (64K =216 بایت) تنظیم کنید. سپس میتوانید با ایجاد چندین ورودی در بوتلودر خود برای هستههایی با اندازههای مختلف صفحه و انتخاب هسته مناسب در زمان بوت، انتخاب کنید که کدام هسته در زمان بوت بوت شود.
برای تأیید اینکه تنظیم اندازه صفحه هسته برای هسته لینوکس فعلی شما چیست، می توانید از ابزار system getconf استفاده کنید. با اندازه صفحه 64K، موارد زیر را نشان می دهند:
$ getconf PAGESIZE 65536نتیجه گیری
به طور خلاصه: تغییر اندازه صفحه حافظه هسته در سیستم های ابری شما می تواند تأثیر مثبتی بر عملکرد برنامه برای بسیاری از بارهای کاری رایج ابری داشته باشد. اگر برنامه شما شامل مقدار زیادی دیسک، حافظه یا ورودی/خروجی شبکه است، ممکن است بتوانید با استفاده از یک هسته با صفحات 16K یا 64K فعال در میزبان های ARM، عملکرد خود را به میزان قابل توجهی بهبود بخشید.
با این حال، این یک نوشدارویی نیست و مسافت پیموده شده شما ممکن است متفاوت باشد. توصیه میکنیم که با تستهای معیار مصنوعی و واقعی تست کنید تا ببینید آیا تغییر اندازه صفحه تأثیر مثبتی بر نتیجه شما دارد یا خیر.
بسیاری از توزیعهای رایج لینوکس با ساختهای Arm64 در حال حاضر چندین هسته را در مخازن توزیع خود دارند. با نصب این بستههای هسته و راهاندازی آنها در هنگام راهاندازی، هزینه آزمایش هستههای بزرگتر برای آزمایش اینکه آیا آنها بهبود عملکرد را ارائه میدهند، نسبتاً کم است.
خبرکاو





ارسال نظر