تحسينات على أداة ART في Android 8.0

تم تحسين "مُشغِّل Android" (ART) بشكل كبير في الإصدار 8.0 من نظام التشغيل Android. تلخِّص القائمة أدناه التحسينات التي يمكن أن يتوقعها مصنعو الأجهزة في ART.

أداة جمع البيانات المهملة المُكثَّفة المتزامنة

كما أعلنّا في مؤتمر Google I/O، يقدّم ART أداة جمع ملفّات برمجية مؤقتة (GC) جديدة متزامنة وكثيفة في Android 8.0. يُكثّف هذا المجمّع الحِزمة في كل مرة يتم فيها تشغيل "جمع القمامة" وأثناء تشغيل التطبيق، مع فترة توقف قصيرة واحدة فقط لمعالجة جذور خيوط المعالجة. في ما يلي مزايا هذا الإجراء:

  • تعمل ميزة "جمع القمامة" دائمًا على تقليل حجم الذاكرة المؤقتة: يقل حجم الذاكرة المؤقتة بنسبة% 32 في المتوسّط مقارنةً بالإصدار 7.0 من Android.
  • تتيح ميزة التجميع تخصيص عنصر مؤشر الزيادة المحلي في سلسلة المهام: تتم عمليات التخصيص بشكل أسرع بنسبة% 70 مقارنةً بنظام التشغيل Android 7.0.
  • توفّر أوقات إيقاف أقصر بنسبة% 85 لاختبار H2 مقارنةً بإدارة الذاكرة في Android 7.0.
  • لم تعُد أوقات الإيقاف المؤقت تتغيّر حسب حجم الحِزمة، ومن المفترض أن تتمكّن التطبيقات من استخدام الحِزم الكبيرة بدون القلق بشأن الانقطاعات.
  • تفاصيل تنفيذ ميزة "جمع القمامة" - حواجز القراءة:
    • حواجز القراءة هي مقدار صغير من العمل الذي يتم إنجازه لكل حقل عنصر يتم قراءته.
    • ويتم تحسين هذه الوظائف في المُجمِّع، ولكن قد تبطئ بعض حالات الاستخدام.

تحسينات الحلقات

تستخدِم أداة ART مجموعة كبيرة من تحسينات الحلقات في إصدار Android 8.0:

  • عمليات إزالة التحقّق من الحدود
    • ثابتة: تم إثبات أنّ النطاقات ضمن الحدود في وقت الترجمة
    • ديناميكي: تضمن اختبارات وقت التشغيل بقاء الحلقات ضمن الحدود (يتم إيقاف التحسين في حال عدم استيفاء هذه الشروط)
  • عمليات إزالة متغيّرات الاستقراء
    • إزالة التعريفات غير الصالحة
    • استبدِل الاستقراء الذي لا يُستخدَم إلا بعد الحلقة بتعبيرات ذات صيغة مغلقة.
  • إزالة الرموز غير الصالحة داخل محتوى الحلقة، وإزالة الحلقات الكاملة التي أصبحت غير صالحة
  • تقليل القوة
  • عمليات تحويل الحلقات: العكس، والتبديل، والقسمة، واللف، وحدوية الوحدات، وما إلى ذلك
  • SIMDization (يُعرف أيضًا باسم Vectorization)

يتوفّر مُحسِّن الحلقات في جولة التحسين الخاصة به في مُجمِّع ART. تشبه معظم تحسينات الحلقات عمليات التحسين والتبسيط في أماكن أخرى. تنشأ تحديات مع بعض التحسينات التي تعيد كتابة CFG بطريقة أكثر تفصيلاً من المعتاد، لأنّ معظم أدوات CFG (راجِع nodes.h) تركّز على إنشاء CFG، وليس إعادة كتابته.

تحليل التسلسل الهرمي للصف

يستخدم ART في Android 8.0 تحليل التسلسل الهرمي للصفوف (CHA)، وهو عملية تحسين للمجمِّع تزيل تحويل المكالمات الافتراضية إلى مكالمات مباشرة استنادًا إلى المعلومات التي يتم إنشاؤها من خلال تحليل التسلسلات الهرميّة للصفوف. المكالمات الافتراضية باهظة التكلفة لأنّه يتم تنفيذها حول البحث في جدول النسخ الاحتياطية، وتستغرق بضع عمليات تحميل تابعة. ولا يمكن أيضًا تضمين المكالمات الافتراضية.

في ما يلي ملخّص للتحسينات ذات الصلة:

  • تعديل حالة طريقة التنفيذ الفردي الديناميكي: في نهاية وقت ربط الصف، عندما تتم تعبئة جدول الفواصل الزمنية، تُجري ART مقارنةً بين كل إدخال وجدول الفواصل الزمنية للصف الأعلى.
  • تحسين المُجمِّع: سيستفيد المُجمِّع من معلومات التنفيذ الفردي لطريقة معيّنة. إذا تم ضبط علامة التنفيذ الفردي على الطريقة A.foo، سيزيل المُجمِّع المعالجة الافتراضية للمكالمة الافتراضية ويحوّلها إلى مكالمة مباشرة، وسيحاول أيضًا تضمين المكالمة المباشرة نتيجةً لذلك.
  • إلغاء صلاحية الرمز المُجمَّع: في نهاية وقت ربط الفئة أيضًا عند تعديل معلومات التنفيذ الفردي، إذا كانت الطريقة A.foo قد كانت في السابق ذات تنفيذ فردي ولكن تم إلغاء صلاحية هذه الحالة الآن، يجب إلغاء صلاحية الرمز المُجمَّع الذي يعتمد على الافتراض بأنّ الطريقة A.foo لها تنفيذ فردي.
  • إلغاء التحسين: بالنسبة إلى الرمز البرمجي المجمّع المباشر المتوفّر في الذاكرة، سيتم بدء عملية إلغاء التحسين لإجبار الرمز البرمجي المجمّع الذي تم إلغاء صلاحيته على الانتقال إلى وضع المترجم لضمان صحة الأداء. سيتم استخدام آلية جديدة لإلغاء التحسين وهي مزيج من إلغاء التحسين المتزامن وغير المتزامن.

ذاكرات التخزين المؤقت المضمّنة في ملفات oat.

يستخدم ART الآن ذاكرات التخزين المؤقت المضمّنة ويُحسِّن مواقع الاتصال التي تتوفّر لها بيانات كافية. تسجِّل ميزة "المخازن المؤقتة المضمّنة" معلومات إضافية عن وقت التشغيل في الملفات الشخصية وتستخدمها لإضافة تحسينات ديناميكية إلى عملية الترجمة المسبقة.

Dexlayout

Dexlayout هي مكتبة تم تقديمها في Android 8.0 لتحليل ملفات dex و إعادة ترتيبها وفقًا لملف شخصي. يهدف Dexlayout إلى استخدام معلومات التحليل في وقت التشغيل لإعادة ترتيب أقسام ملف dex أثناء تجميع الصيانة غير النشطة على الجهاز. من خلال تجميع أجزاء ملف dex التي يتم الوصول إليها معًا غالبًا، يمكن للبرامج استخدام أنماط أفضل للوصول إلى الذاكرة من خلال تحسين الأداء المحلي، وتوفير ذاكرة الوصول العشوائي وتقليل وقت بدء التشغيل.

بما أنّ معلومات الملف الشخصي لا تتوفّر حاليًا إلا بعد تشغيل التطبيقات، يتم دمج dexlayout في عملية الترجمة على الجهاز من خلال dex2oat أثناء صيانة وضع السكون.

إزالة ذاكرة التخزين المؤقت في Dex

حتى إصدار Android 7.0، كان عنصر DexCache يمتلك أربع صفائف كبيرة، تكون تناسبية مع عدد عناصر معيّنة في DexFile، وهي:

  • سلاسل (مرجع واحد لكل DexFile::StringId)
  • أنواع (مرجع واحد لكل DexFile::TypeId)
  • الطرق (مُشارِك إشارة برمجية أصلية لكل DexFile::MethodId)
  • حقول (مُشارِك أصلي واحد لكل DexFile::FieldId)

تم استخدام هذه الصفائف لاسترداد العناصر التي سبق أن تم حلّها بسرعة. في Android 8.0، تمت إزالة جميع المصفوفات باستثناء صفيف الطرق.

أداء المترجم

تحسّن أداء المُفسِّر بشكلٍ كبير في الإصدار 7.0 من نظام Android مع تقديم "mterp"، وهو مُفسِّر يضمّ آلية أساسية لاسترداد/ترميز/تفسير التعليمات مكتوبة بلغة التجميع. تم وضع نموذج لواجهة Mterp استنادًا إلى مترجم Dalvik السريع، وهي تتوافق مع arm وarm64 وx86 وx86_64 وmips وmips64. بالنسبة إلى الرموز البرمجية الحسابية، يُعدّ mterp في Art مشابهًا تقريبًا للمترجم السريع في Dalvik. ومع ذلك، يمكن أن يكون الإجراء في بعض الحالات أبطأ بشكلٍ كبير، أو حتى بشكلٍ كبير جدًا:

  1. استدعاء الأداء
  2. التلاعب بالسلاسل، ومستخدمو الأساليب المكثّفون الآخرون الذين يستخدمون ميزات متأصلة في Dalvik
  3. استخدام أعلى لذاكرة الحزمة

يعالج نظام التشغيل Android 8.0 هذه المشاكل.

المزيد من عمليات التضمين

منذ الإصدار 6.0 من نظام التشغيل Android، يمكن لاتّباع ART تضمين أيّ طلب ضمن ملفات dex نفسها، ولكن يمكنه تضمين طرق الأوراق من ملفات dex مختلفة فقط. كان هناك سببان لتحديد هذا الحدّ:

  1. تتطلّب الإدراج من ملف dex آخر استخدام ذاكرة التخزين المؤقت لملف dex الآخر، على عكس إدراج ملف dex نفسه، الذي يمكنه إعادة استخدام ذاكرة التخزين المؤقت لملف dex للمُستخدِم. تكون ذاكرة التخزين المؤقت لملف dex مطلوبة في الرمز المجمّع لبعض التعليمات، مثل عمليات الاتصال الثابت أو تحميل السلسلة أو تحميل الفئة.
  2. لا تُشفِّر خرائط الحِزم سوى فهرس الأسلوب ضمن ملف dex الحالي.

لحلّ هذه القيود، يقدّم نظام Android 8.0 ما يلي:

  1. إزالة إمكانية الوصول إلى ذاكرة التخزين المؤقت dex من الرمز البرمجي المجمَّع (راجِع أيضًا قسم "إزالة ذاكرة التخزين المؤقت dex")
  2. توسيع نطاق ترميز خريطة الحزمة

تحسينات على المزامنة

عدّل فريق ART مسارات الرموز البرمجية MonitorEnter/MonitorExit، وقلّل من اعتمادنا على حواجز الذاكرة التقليدية على ARMv8، واستبدلها بتعليمات (acquire/release) أحدث كلما أمكن ذلك.

الطرق الأصلية الأسرع

تتوفّر مكالمات أصلية أسرع إلى Java Native Interface (JNI) باستخدام التعليقات التوضيحية @FastNative و@CriticalNative. تعمل تحسينات وقت التشغيل المضمّنة في ART على تسريع عمليات النقل باستخدام واجهة برمجة التطبيقات JNI واستبدال !bang JNI الذي تم إيقافه نهائيًا الآن. لا تؤثر التعليقات التوضيحية في الطرق غير الأصلية ولا تتوفّر إلا لرمز لغة Java للنظام الأساسي على bootclasspath (بدون تحديثات من "متجر Play").

يتيح التعليق التوضيحي @FastNative استخدام الطرق غير الثابتة. استخدِم هذه العلامة إذا كانت إحدى الطرق تُدخل jobject كمَعلمة أو قيمة معروضة.

يقدّم التعليق التوضيحي @CriticalNative طريقة أسرع لتنفيذ methods المدمجة مع المحتوى، مع القيود التالية:

  • يجب أن تكون الطرق ثابتة، أي بدون عناصر للمَعلمات أو القيم المعروضة أو this الضمني.
  • يتم تمرير الأنواع الأساسية فقط إلى الطريقة الأصلية.
  • لا تستخدم الطريقة الأصلية المَعلمتَين JNIEnv و jclass في تعريف الدالة.
  • يجب تسجيل الطريقة باستخدام RegisterNatives بدلاً من الاعتماد على ربط JNI الديناميكي.

يمكن أن تُحسِّن @FastNative أداء الطريقة المدمجة مع المحتوى بمقدار 3 أضعاف، و @CriticalNative بمقدار 5 أضعاف. على سبيل المثال، انتقال JNI تم قياسه على جهاز Nexus 6P:

طلب Java Native Interface (JNI) وقت التنفيذ (بالنانو ثانية)
JNI العادي 115
!bang JNI 60
@FastNative 35
@CriticalNative 25