Facebook مفتوح المصدر Cinder، وهو شوكة من CPython يستخدمه Instagram

نشر فيسبوك الكود المصدري لمشروع Cinder، وهو شوكة لـ CPython 3.8.5، وهو التطبيق المرجعي الرئيسي للغة البرمجة Python. يتم استخدام Cinder في البنية التحتية لإنتاج Facebook لتشغيل Instagram ويتضمن تحسينات لتحسين الأداء.

تم نشر الكود لمناقشة إمكانية نقل التحسينات المعدة إلى إطار عمل CPython الرئيسي ولمساعدة المشاريع الأخرى المشاركة في تحسين أداء CPython. لا ينوي Facebook دعم Cinder في شكل مشروع منفصل مفتوح المصدر ويتم تقديم الكود بالشكل الذي يتم استخدامه به في البنية التحتية للشركة، دون تمشيط وتوثيق إضافي. كما أنهم لا يحاولون الترويج لـ Cinder كبديل لـ CPython - فالهدف الرئيسي للتطوير هو الرغبة في تحسين CPython نفسه.

يُشار إلى كود Cinder على أنه موثوق إلى حد ما وتم اختباره في بيئات الإنتاج، ولكن إذا تم تحديد المشكلات، فسيتعين عليك حلها بنفسك، نظرًا لأن Facebook لا يضمن أنه سيستجيب لرسائل الخطأ الخارجية وطلبات السحب. في الوقت نفسه، لا يستبعد Facebook التعاون البناء مع المجتمع وهو مستعد لمناقشة الأفكار حول كيفية جعل Cinder أسرع أو كيفية تسريع نقل التغييرات المعدة إلى الجزء الرئيسي من CPython.

التحسينات الرئيسية التي تم تنفيذها في Cinder:

  • التخزين المؤقت المضمن للكود الثانوي ("رمز البايت الظل"). جوهر هذه الطريقة هو تحديد المواقف التي يتم فيها تنفيذ كود تشغيل نموذجي يمكن تحسينه، واستبدال كود التشغيل هذا ديناميكيًا بخيارات متخصصة أسرع (على سبيل المثال، استبدال الوظائف التي يتم استدعاؤها بشكل متكرر).
  • تقييم كوروتين حريص. بالنسبة لاستدعاءات الدوال غير المتزامنة التي تتم معالجتها على الفور (لا يؤدي الانتظار إلى الانتظار وتصل الدالة إلى بيان الإرجاع مبكرًا)، يتم استبدال نتيجة هذه الوظائف مباشرة دون إنشاء كوروتين أو تضمين حلقة حدث. في كود Facebook الذي يستخدم بشكل كبير المزامنة/الانتظار، يؤدي التحسين إلى تسريع بنسبة 5% تقريبًا.
  • تجميع JIT الانتقائي على مستوى الأساليب والوظائف الفردية (الطريقة في كل مرة). يتم تمكينه عبر خيار "-X jit" أو متغير البيئة PYTHONJIT=1 ويسمح لك بتسريع تنفيذ العديد من اختبارات الأداء بمقدار 1.5 إلى 4 مرات. نظرًا لأن تجميع JIT مناسب فقط للوظائف التي يتم تنفيذها بشكل متكرر، فمن غير المستحسن استخدامه للوظائف التي نادرًا ما تستخدم، والتي يمكن أن يؤدي عبء التجميع الخاص بها إلى إبطاء تنفيذ البرنامج فقط.

    من خلال الخيار "-X jit-list-file=/path/to/jitlist.txt" أو متغير البيئة "PYTHONJITLISTFILE=/path/to/jitlist.txt" يمكنك تحديد ملف بقائمة من الوظائف التي من أجلها JIT يمكن استخدامه (تنسيق المسار .to.module:funcname أو path.to.module:ClassName.method_name). يمكن تحديد قائمة الوظائف التي يجب تمكين JIT لها بناءً على نتائج التوصيف. في المستقبل، من المتوقع دعم تجميع JIT الديناميكي بناءً على التحليل الداخلي لتكرار استدعاءات الوظائف، ولكن مع الأخذ في الاعتبار تفاصيل عمليات الإطلاق على Instagram، فإن تجميع JIT مناسب أيضًا لـ Facebook في المرحلة الأولية.

    تقوم JIT أولاً بتحويل كود Python الثانوي إلى تمثيل متوسط ​​عالي المستوى (HIR)، وهو قريب إلى حد ما من Python bytecode، ولكنه مصمم لاستخدام جهاز ظاهري قائم على التسجيل بدلاً من جهاز قائم على المكدس، ويستخدم أيضًا معلومات النوع ومعلومات إضافية التفاصيل المهمة للأداء (مثل حساب المراجع). يتم بعد ذلك تحويل HIR إلى نموذج SSA (مهمة فردية ثابتة) ويمر عبر خطوات التحسين التي تأخذ في الاعتبار نتائج العد المرجعي وبيانات استهلاك الذاكرة. ونتيجة لذلك، يتم إنشاء تمثيل متوسط ​​منخفض المستوى (LIR)، قريب من لغة التجميع. بعد مرحلة أخرى من التحسينات المستندة إلى LIR، يتم إنشاء تعليمات التجميع باستخدام مكتبة asmjit.

  • الوضع الصارم للوحدات. تتضمن الوظيفة ثلاثة مكونات: اكتب StrictModule. محلل ثابت يمكنه تحديد أن تنفيذ الوحدة ليس له أي تأثير على التعليمات البرمجية خارج تلك الوحدة. مُحمل الوحدة النمطية الذي يحدد أن الوحدات النمطية في الوضع الصارم (يحدد الكود "import __strict__")، ويتحقق من عدم وجود تقاطعات مع الوحدات النمطية الأخرى، ويقوم بتحميل الوحدات النمطية الصارمة في sys.modules ككائن StrictModule.
  • Static Python هو مترجم تجريبي للكود الثانوي يستخدم التعليقات التوضيحية للنوع لإنشاء كود بايت خاص بالنوع والذي يعمل بشكل أسرع بفضل تجميع JIT. في بعض الاختبارات، أظهر الجمع بين Static Python وJIT تحسينات في الأداء تصل إلى 7 مرات مقارنة بـ CPython القياسي. في كثير من الحالات، تُقدر النتائج بأنها قريبة من استخدام المترجمين MyPyC وCython.

المصدر: opennet.ru

إضافة تعليق