لینک کوتاه مطلب : https://hsgar.com/?p=4977

چارچوب یادگیری ماشین برای بهینه سازی کامپایلر

این سوال که چگونه می توان کدهای سریعتر و کوچکتر را کامپایل کرد، همراه با تولد کامپیوترهای مودم مطرح شد. بهینه سازی کد بهتر می تواند هزینه عملیاتی برنامه های بزرگ مرکز داده را به میزان قابل توجهی کاهش دهد. اندازه کدهای کامپایل شده بیشترین اهمیت را برای سیستم های موبایل و جاسازی شده یا نرم افزارهای مستقر شده روی آن دارد پارتیشن های بوت امن، که در آن باینری کامپایل شده باید در بودجه های اندازه کد تنگ قرار گیرد. با پیشرفت در این زمینه، فضای سر به شدت فشرده شده است و به طور فزاینده ای پیچیده شده است اکتشافی، مانع از نگهداری و بهبودهای بیشتر می شود.

اخیر پژوهش نشان داده است که یادگیری ماشین (ML) می‌تواند فرصت‌های بیشتری را در بهینه‌سازی کامپایلر با جایگزینی اکتشافی‌های پیچیده با سیاست‌های ML باز کند. با این حال، پذیرش ML در کامپایلرهای همه منظوره و با قدرت صنعتی همچنان یک چالش است.

برای پرداختن به این موضوع، «MLGO: چارچوب بهینه سازی کامپایلر هدایت شده با یادگیری ماشین“، اولین چارچوب عمومی درجه صنعتی برای ادغام تکنیک های ML به طور سیستماتیک در LLVM (یک زیرساخت کامپایلر صنعتی منبع باز که برای ساختن نرم افزارهای حیاتی و با کارایی بالا در همه جا حاضر است). MLGO از یادگیری تقویتی (RL) برای آموزش شبکه های عصبی برای اتخاذ تصمیماتی استفاده می کند که می تواند جایگزین اکتشافی در LLVM شود. ما دو بهینه سازی MLGO را برای LLVM توصیف می کنیم: 1) کاهش اندازه کد با درون خطی. و 2) بهبود عملکرد کد با تخصیص ثبت (regalloc). هر دو بهینه سازی در دسترس هستند مخزن LLVM، و در تولید مستقر شده اند.

MLGO چگونه کار می کند؟ با Inlining-for-Size به عنوان مطالعه موردی

خط کشی با اتخاذ تصمیماتی که حذف کد اضافی را ممکن می سازد، به کاهش اندازه کد کمک می کند. در مثال زیر، تابع تماس گیرنده است foo() تابع callee را فراخوانی می کند bar()، که خود به آن می گویند baz(). داخل کردن هر دو callsite یک ساده را برمی گرداند foo() عملکردی که اندازه کد را کاهش می دهد.

Inlining با حذف کد اضافی، اندازه کد را کاهش می دهد.

در کد واقعی، هزاران تابع وجود دارد که یکدیگر را فراخوانی می کنند، و بنابراین شامل a می شوند نمودار تماس. در طول مرحله inlining، کامپایلر تراورس می کند روی نمودار فراخوانی روی همه جفت‌های تماس گیرنده و تماس گیرنده، تصمیم می‌گیرد که آیا یک جفت تماس گیرنده-کالی را درون خط قرار دهد یا خیر. این یک فرآیند تصمیم گیری متوالی است زیرا تصمیمات خطی قبلی نمودار فراخوانی را تغییر می دهد و بر تصمیمات بعدی و نتیجه نهایی تأثیر می گذارد. در مثال بالا، گراف تماس foo()bar()baz() برای کاهش اندازه کد به یک تصمیم “بله” در هر دو لبه نیاز دارد.

قبل از MLGO، تصمیم درونی/بدون خطی توسط یک اکتشافی گرفته می شد که با گذشت زمان، بهبود آن به طور فزاینده ای دشوار می شد. MLGO اکتشافی را با یک مدل ML جایگزین می کند. در طول پیمایش گراف فراخوانی، کامپایلر به دنبال مشاوره از یک شبکه عصبی در مورد اینکه آیا باید یک جفت تماس گیرنده و تماس گیرنده خاص را با تغذیه ویژگی‌های مربوطه (یعنی ورودی‌ها) از نمودار درون خطی کند یا خیر، می‌خواهد و تصمیمات را به صورت متوالی اجرا می‌کند تا زمانی که کل گراف فراخوانی طی شود. .

تصویر MLGO در حین خط کشی. «#bbs»، «#users» و «ارتفاع سایت تماس» نمونه‌ای از ویژگی‌های جفت تماس گیرنده و تماس گیرنده هستند.

MLGO شبکه تصمیم گیری (خط مشی) را با استفاده از RL آموزش می دهد شیب سیاست و استراتژی های تکامل الگوریتم ها در حالی که هیچ حقیقتی در مورد بهترین تصمیم ها وجود ندارد، RL آنلاین بین آموزش و تدوین با خط مشی آموزش دیده برای جمع آوری داده ها و بهبود خط مشی تکرار می شود. به طور خاص، با توجه به مدل فعلی تحت آموزش، کامپایلر مدل را برای تصمیم گیری درون خطی/بدون خطی در طول مرحله درون خطی مشاوره می کند. پس از اتمام کامپایل، گزارشی از فرآیند تصمیم گیری متوالی (وضعیت، اقدام، پاداش) تولید می کند. سپس گزارش برای به روز رسانی مدل به مربی ارسال می شود. این روند تا زمانی که به یک مدل رضایت بخش دست یابیم تکرار می شود.

رفتار کامپایلر در حین آموزش کامپایلر کد منبع را کامپایل می کند foo.cpp به یک فایل شی foo.o با دنباله ای از پاس های بهینه سازی که یکی از آنها پاس درون خطی است.

سپس خط مشی آموزش دیده در کامپایلر تعبیه می شود تا تصمیمات درون خطی/بدون خطی در طول کامپایل ارائه شود. برخلاف سناریوی آموزشی، این خط مشی گزارشی تولید نمی کند. را TensorFlow مدل تعبیه شده است XLA AOT، که مدل را به کد اجرایی تبدیل می کند. این امر از وابستگی و سربار زمان اجرا TensorFlow جلوگیری می کند و زمان اضافی و هزینه حافظه را که توسط استنتاج مدل ML در زمان کامپایل معرفی می شود به حداقل می رساند.

رفتار کامپایلر در تولید

ما خط مشی inlining-for-size را روی یک بسته نرم افزاری داخلی بزرگ حاوی 30 هزار ماژول آموزش دادیم. خط مشی آموزش دیده زمانی قابل تعمیم است که برای کامپایل نرم افزارهای دیگر اعمال شود و به کاهش اندازه 3 تا 7 درصد دست یابد. علاوه بر تعمیم پذیری در سراسر نرم افزار، تعمیم پذیری در طول زمان نیز مهم است – هم نرم افزار و هم کامپایلر در حال توسعه فعال هستند، بنابراین خط مشی آموزش دیده باید عملکرد خوب را برای مدت زمان معقولی حفظ کند. ما عملکرد مدل را در همان مجموعه نرم افزاری سه ماه بعد ارزیابی کردیم و فقط کاهش جزئی پیدا کردیم.

درصد کاهش اندازه خط مشی خطی برای اندازه. محور x نرم افزارهای مختلفی را ارائه می دهد و محور y نشان دهنده درصد کاهش اندازه است. “Training” نرم افزاری است که مدل بر روی آن آموزش داده شده است و “Infra[1|2|3]” بسته های نرم افزاری داخلی مختلف هستند.

آموزش MLGO inlining-for-size به کار گرفته شده است فوشیا – یک سیستم عامل متن باز با هدف عمومی که برای تامین انرژی اکوسیستم متنوعی از سخت افزار و نرم افزار طراحی شده است، جایی که اندازه باینری بسیار مهم است. در اینجا، MLGO کاهش اندازه 6.3 درصدی را برای واحدهای ترجمه C++ نشان داد.

ثبت-تخصیص (برای عملکرد)

به عنوان یک چارچوب کلی، ما از MLGO برای بهبود استفاده کردیم ثبت نام مجوز تخصیص، که عملکرد کد را در LLVM بهبود می بخشد. ثبت تخصیص مشکل تخصیص را حل می کند ثبت های فیزیکی به محدوده های زنده (یعنی متغیرها).

همانطور که کد اجرا می‌شود، محدوده‌های زنده مختلف در زمان‌های مختلف تکمیل می‌شوند و رجیسترها را برای استفاده در مراحل پردازش بعدی آزاد می‌کنند. در مثال زیر، هر دستور «add» و «multiply» به همه عملوندها و نتیجه در ثبات های فیزیکی نیاز دارد. محدوده زنده ایکس به رجیستر سبز تخصیص داده می شود و قبل از محدوده زنده در رجیسترهای آبی یا زرد تکمیل می شود. بعد از ایکس تکمیل می شود، ثبت سبز در دسترس می شود و به محدوده زنده اختصاص می یابد تی.

مثال تخصیص ثبت نام.

وقتی زمان اختصاص محدوده زنده فرا می رسد q، هیچ رجیستر موجودی وجود ندارد، بنابراین مجوز تخصیص رجیستر باید تصمیم بگیرد که (در صورت وجود) کدام محدوده زنده را می توان از رجیستر آن “اخراج” کرد تا فضا برای آن ایجاد شود. q. این به عنوان مشکل “اخراج محدوده زنده” نامیده می شود، و تصمیمی است که برای آن مدل را آموزش می دهیم تا جایگزین اکتشافی های اصلی شود. در این مثال خاص، اخراج می کند z از رجیستر زرد، و آن را به q و نیمه اول z.

اکنون نیمه دوم تعیین نشده محدوده زنده را در نظر می گیریم z. ما دوباره درگیری داریم و این بار محدوده زنده تی اخراج می شود و تقسیم می شود و نیمه اول تی و قسمت پایانی z در نهایت از ثبت نام سبز استفاده کنید. قسمت میانی از z مطابق با دستورالعمل است q = تی * y، جایی که z استفاده نمی شود، بنابراین به هیچ ثباتی اختصاص داده نمی شود و مقدار آن در پشته ای از ثبات زرد ذخیره می شود، که بعداً در ثبات سبز بارگذاری می شود. همین اتفاق برای تی. این دستورات بارگذاری/ذخیره اضافی را به کد اضافه می کند و عملکرد را کاهش می دهد. هدف الگوریتم تخصیص رجیستر کاهش چنین ناکارآمدی تا حد امکان است. این به عنوان پاداش برای هدایت آموزش خط مشی RL استفاده می شود.

مشابه خط‌مشی Inlining-for-Size، خط‌مشی تخصیص ثبت (regalloc-for-performance) بر روی یک بسته نرم‌افزار داخلی بزرگ Google آموزش داده شده است و در نرم‌افزارهای مختلف قابل تعمیم است، با 0.3% ~1.5% بهبود در پرس و جو در ثانیه (QPS) روی مجموعه ای از برنامه های کاربردی مرکز داده در مقیاس بزرگ داخلی. بهبود QPS برای ماه‌ها پس از استقرار آن ادامه داشته است و قابلیت تعمیم‌پذیری مدل را در افق زمانی نشان می‌دهد.

نتیجه گیری و کار آینده

ما MLGO را پیشنهاد می کنیم، چارچوبی برای ادغام تکنیک های ML به طور سیستماتیک در یک کامپایلر صنعتی، LLVM. MLGO یک چارچوب کلی است که می توان آن را گسترش داد: 1) عمیق تر، به عنوان مثال، افزودن ویژگی های بیشتر، و اعمال الگوریتم های RL بهتر. و 2) گسترده تر، با استفاده از آن برای اکتشافات بهینه سازی بیشتر فراتر از inlining و regalloc. ما مشتاق امکاناتی هستیم که MLGO می‌تواند در حوزه بهینه‌سازی کامپایلر ایجاد کند و مشتاقانه منتظر پذیرش بیشتر آن و مشارکت‌های آتی جامعه تحقیقاتی هستیم.

خودت آن را امتحان کن

راه حل آموزش و جمع آوری داده های منبع باز را بررسی کنید github و الف نسخه ی نمایشی که از گرادیان خط مشی برای آموزش خط مشی خطی برای اندازه استفاده می کند.

سپاسگزاریها

مایلیم از مشارکت کنندگان و همکاران MLGO، یوجین برودو، ژاکوب هگنا، گاوراو جین، دیوید لی، زینان لین، کشتیج ماهاجان، جک موریس، گیریش مورورو، جین شین نگ، رابرت اورمندی، ایسواران رامان، اوندرج سیکورا، معروف زابر، تشکر کنیم. ویه ژائو. همچنین از پتر هوسک، یوکیان لی، رولاند مک گرات، هاووی وو برای اعتماد به ما و استقرار MLGO در فوشیا به عنوان اولین مشتری MLGO تشکر می کنیم. از دیوید بلیکی، اریک کریستوفر، بروکس موزس، جردن روپرشت برای کمک به استقرار MLGO در برنامه‌های مرکز داده داخلی Google در مقیاس بزرگ تشکر می‌کنیم. و از اد چی، تیپ موزلی برای حمایت رهبریشان تشکر کنید.

لینک منبع

ارسال یک پاسخ

آدرس ایمیل شما منتشر نخواهد شد.