۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

پایتون برای حذف GIL و تقویت همزمانی حرکت می کند

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

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

پس از بحث‌های فراوان، شورای راهبری پایتون قصد دارد پیشنهادی را تأیید کند، PEP 703، “اختیاری کردن قفل مترجم جهانی در CPython.”

این پیشنهاد نقطه اوج تلاش‌های بسیاری در طول سال‌ها برای حذف قفل Interpter Global Python یا GIL است. حذف GIL مانع بزرگی را بر سر راه چند رشته ای از بین می برد و پایتون را به یک زبان واقعاً چند هسته ای تبدیل می کند و عملکرد آن را برای بارهای کاری که از موازی سازی بهره می برند به طور قابل توجهی بهبود می بخشد.

با این پیشنهاد، پشتیبانی درجه یک از multithreading و همزمانی در Python یک گام به واقعیت نزدیک‌تر است.

چرا GIL پایتون را حذف کنیم؟

سیستم مدیریت حافظه پایتون با حفظ تعداد ارجاعات به هر شی، میزان استفاده از شی را پیگیری می کند. هنگامی که تعداد مراجع برای یک شی به صفر می رسد، شیء برای حذف در نظر گرفته می شود.

از آنجایی که پایتون در زمانی ایجاد شد که سیستم‌های چند پردازنده‌ای نادر بودند و پردازنده‌های چند هسته‌ای وجود نداشتند، این مکانیسم شمارش مرجع برای رشته‌ها ایمن نیست. درعوض، پایتون با اجازه دادن به تنها یک رشته برای دسترسی به یک شی در یک زمان، ایمنی رشته را به دست می آورد. این هدف GIL است.

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

توسعه‌دهندگان اصلی پایتون سرانجام تصمیم گرفتند GIL را از CPython حذف کنند، اما فقط در صورتی که بدون کاهش سرعت برنامه‌های تک رشته‌ای انجام شود.

چگونه پایتون بدون GIL کار خواهد کرد

پیشنهادهای کنونی برای نسخه بدون GIL پایتون از ترکیبی از تکنیک‌ها برای ایمن کردن رشته شمارش مرجع استفاده می‌کنند، و سرعت برنامه‌های تک رشته‌ای را دست نخورده می‌گذارند یا به حداقل می‌رسانند.

  • شمارش ارجاع مغرضانه. شمارش اشیایی که تنها با یک رشته به آنها دسترسی پیدا می‌کند، متفاوت (و سریع‌تر) از تعداد اشیایی که توسط رشته‌های مختلف به آن‌ها دسترسی دارند، مدیریت می‌شوند. از آنجایی که بیشتر اشیا تنها با یک رشته قابل دسترسی هستند، تأثیر آن بر برنامه های تک رشته ای به حداقل می رسد.
  • جاودانه‌سازی. برخی از اشیا، مانند هیچ‌کدام، هرگز نیازی به جابجایی ندارند، بنابراین تعداد مراجع آنها نیازی به ردیابی ندارد.
  • تخصیص حافظه ایمن رشته ای. یک سیستم تخصیص حافظه جدید برای اشیاء CPython ردیابی اشیاء در زباله جمع کن و تخصیص حافظه به روشی ایمن را آسان تر می کند.
  • شمارش ارجاع معوق. شمارش مراجع برای برخی از اشیا، مانند توابع سطح بالا در یک ماژول، می‌تواند با خیال راحت به تعویق بیفتد. این باعث صرفه جویی در زمان و منابع می شود.
  • جمع‌کننده زباله اصلاح‌شده. جمع‌آورنده زباله CPython مراجع چرخه‌ای اشیاء را تمیز می‌کند، جایی که دو یا چند شیء به یکدیگر ارجاع دارند. ساختار no-GIL تغییرات زیادی را در جمع کننده زباله ایجاد می کند ، مانند حذف سیستم “نسل” برای ردیابی اشیاء.

چگونه پایتون بدون GIL وارد مرحله اجرا می شود

اجرای PEP 703 یک پروژه بلندمدت است که در چند مرحله طی چندین سال انجام خواهد شد. در طول این مدت، مفسر CPython تغییر می کند تا نسخه بدون GIL ابتدا اختیاری، سپس پشتیبانی شود، و در نهایت نسخه استاندارد CPython.

برای انجام این کار، توسعه‌دهندگان CPython یک حالت آزمایشی build “no-GIL” را به CPython اضافه می‌کنند تا بتوان نسخه‌ای از CPython را با یا بدون GIL کامپایل کرد. در نهایت، ساخت no-GIL به صورت پیش‌فرض تبدیل می‌شود.

در اینجا نحوه اجرای طرح حذف GIL از CPython تنظیم شده است.

مرحله ۱: No-GIL CPython اختیاری است

اولین تجسم‌های یک CPython بدون GIL، هم برای توسعه‌دهندگان CPython و هم برای جامعه بزرگ‌تر Python، آزمایشی خواهند بود. این مرحله آزمایشی چندین هدف دارد:

  • بقیه جامعه پایتون را درگیر کنید. هر تغییر عمده در پایتون نیاز به خرید از جامعه گسترده‌تر پایتون دارد. ساخت‌های آزمایشی راهی را به کاربران پایتون می‌دهند تا با خیال راحت کد خود را آزمایش کنند و ببینند کدهای بدون رشته و رشته‌ای چگونه رفتار خواهند کرد.
  • به توزیع‌های پایتون گزینه ارسال پایتون بدون GIL را بدهید، نه الزام را. توزیع‌های پایتون مانند Conda یا WinPython باید سازگاری با CPython موجودی را تضمین کنند. در طول مرحله انتقال، آنها می توانند گزینه نصب نسخه معمولی یا بدون GIL CPython را ارائه دهند. این به کاربران Conda یا WinPython اجازه می‌دهد تا بهترین نسخه سازگار با نیازهای خود را انتخاب کنند.
  • تعیین کنید که آیا پروژه بدون GIL ارزشمند است یا خیر. اگر جامعه ساخت‌های بدون GIL را در مقیاس آزمایش کند و از نتایج ناراضی باشد، توسعه‌دهندگان اصلی CPython حق عقب‌نشینی را برای خود محفوظ می‌دارند. داشتن دو ساخت به معنای بار تعمیر و نگهداری سنگین‌تر در کوتاه‌مدت است، اما اگر پروژه بدون GIL ارزشش را نداشته باشد، راه فراری را فراهم می‌کند.

مرحله ۲: No-GIL CPython پشتیبانی می شود

مرحله بعدی ارائه بیلد no-GIL به عنوان یک ساخت جایگزین پشتیبانی شده برای CPython خواهد بود. کاربر می‌تواند یکی از دو نسخه بدون GIL یا GIL را نصب کند، که یکی از آنها نسخه رسمی پشتیبانی شده از CPython است که رفع اشکال، وصله‌های امنیتی و به‌روزرسانی‌ها را دریافت می‌کند.

یکی از اهداف بزرگ این مرحله تعیین تاریخ هدف برای پیش‌فرض کردن No-GIL است. این احتمالاً در همان جدول زمانی با حذف و حذف سایر ویژگی‌های پایتون اتفاق می‌افتد – حداقل دو یا سه نسخه، یعنی حداقل دو یا سه سال.

مرحله ۳: No-GIL CPython پیش فرض است

مرحله آخر این است که نسخه بدون GIL CPython را به صورت پیش‌فرض قرار دهیم و همه کدهای مرتبط با GIL را از CPython حذف کنیم. توماس واترز، توسعه دهنده هسته CPython نوشت، “زیرا داشتن دو حالت ساخت مشترک ممکن است بار سنگینی بر دوش جامعه باشد (به عنوان به عنوان مثال، می تواند منابع تست و سناریوهای اشکال زدایی را دو برابر کند)، اما ما نیز نمی توانیم عجله کنیم. ما فکر می کنیم ممکن است پنج سال طول بکشد تا به این مرحله برسیم.”

بزرگترین چالش ها برای حذف GIL

بزرگترین چالش‌های موجود در این طرح فقط فنی نیستند، اگرچه چالش‌های فنی دلهره‌آور هستند. چیزی که حتی بزرگتر به نظر می رسد این است که چگونه می توان بقیه اکوسیستم پایتون را با این تغییرات مطابقت داد — و مطمئن شوید که پایتون بدون GIL بیش از آنچه حل می کند، مشکلاتی ایجاد نمی کند.

طبق گفته Wouters، “… هر گونه تغییر در کد شخص ثالث مورد نیاز برای تطبیق بیلدهای بدون GIL باید فقط در ساخت‌های با GIL کار کند (اگرچه سازگاری با نسخه‌های قدیمی‌تر پایتون همچنان باید بررسی شود).

چالش بزرگ دیگر، همانطور که در بالا ذکر شد، این است که “به همراه داشتن بقیه جامعه پایتون”، ووترز، “… و مطمئن شوید که تغییراتی که می‌خواهیم ایجاد کنیم، و تغییراتی که می‌خواهیم آنها انجام دهند. ، خوش طعم هستند.

ووترز گفت: «قبل از اینکه به طور کامل به ساخت بدون GIL روی بیاوریم، باید شاهد حمایت جامعه از آن باشیم. «ما نمی‌توانیم پیش‌فرض را تغییر دهیم و انتظار داشته باشیم که جامعه بفهمد برای پشتیبانی از آن چه کاری باید انجام دهد.»

جامعه Python هنگام انتقال از Python 2 به Python 3 دردسرهای بزرگی را تجربه کرد، بنابراین هرگونه تغییر بزرگ مانند حذف GIL باید کاملاً با عقب سازگار باشد. همانطور که Wouters بیان می کند، “ما وضعیت دیگری در پایتون ۳ نمی خواهیم.”

فراتر از خطرات و چالش ها، یک پاداش بزرگ نهفته است: پایتونی که در نهایت از موازی کاری که برنامه نویسان در قرن بیست و یکم انتظار داشتند، پشتیبانی می کند.