التحليل باستخدام عرض وحدة معالجة الرسومات للملف الشخصي

تشير أداة رسم مخطط لعرض GPU إلى الوقت النسبي الذي تستغرقه كل مرحلة من مراحل مسار العرض لعرض اللقطة السابقة. يمكن أن تساعدك هذه المعرفة في تحديد نقاط التوقف في عملية العرض، حتى تتمكّن من معرفة ما يجب تحسينه لتحسين أداء عرض تطبيقك.

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

التمثيل المرئي

تعرض أداة العرض على وحدة معالجة الرسومات "Profile GPU" المراحل وأوقاتها النسبية في شكل رسم بياني: "مدرّج تكراري" مصنَّف حسب اللون. يوضح الشكل 1 مثالاً لمثل هذه الشاشة.

الشكل 1. الرسم البياني لعرض وحدة معالجة الرسومات في الملف الشخصي

يمثّل كل جزء من كل شريط عمودي معروض في الرسم البياني "عرض GPU للملف الشخصي" مرحلة من مراحل مسار المعالجة ويتم تمييزه باستخدام لون معيّن في الرسم البياني الشريطي. يعرض الشكل 2 مفتاحًا لمعنى كل لون معروض.

الشكل 2. وسيلة إيضاح الرسم البياني لعرض وحدة معالجة الرسومات في الملف الشخصي

بعد فهم ما يشير إليه كل لون، يمكنك استهداف جوانب معيّنة في تطبيقك لمحاولة تحسين أداء العرض.

المراحل ومعانيها

يوضّح هذا القسم ما يحدث خلال كل مرحلة تقابل لونًا في الشكل 2، بالإضافة إلى أسباب الاختناقات التي يجب الانتباه إليها.

معالجة الإدخال

تقيس مرحلة معالجة الإدخال في مسار الإحالة الناجحة المدة التي قضى التطبيقها في معالجة أحداث الإدخال. يشير هذا المقياس إلى المدة التي قضّاها التطبيق في تنفيذ الرمز البرمجي الذي تم استدعاؤه نتيجةً لطلبات إعادة الاتصال بأحداث الإدخال.

عندما تكون هذه الشريحة كبيرة

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

يُرجى العلم أيضًا أنّه RecyclerView يمكن أن يظهر شريط التمرير في هذه المرحلة. ينتقل RecyclerView مباشرةً عند استهلاك حدث اللمس. ونتيجة لذلك، يمكن أن تضخّم مشاهدات العناصر الجديدة أو تملأها. لهذا السبب، من المهم إتمام هذه العملية في أسرع وقت ممكن. يمكن أن تساعدك أدوات التعريف مثل Traceview أو Systrace في إجراء مزيد من التحقيق.

Animation

توضح لك مرحلة الرسوم المتحركة المدة التي استغرقتها لتقييم جميع الرسوم المتحركة التي كانت تعمل في هذا الإطار. أكثر أنواع الصور المتحركة شيوعًا هي "ObjectAnimator" و"ViewPropertyAnimator" و"الانتقالات".

عندما تكون هذه الشريحة كبيرة

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

قياس/تخطيط

لكي يرسم نظام التشغيل Android عناصر العرض على الشاشة، ينفِّذ عمليتين محدّدتين على مستوى التنسيقات وطرق العرض في التسلسل الهرمي لطريقة العرض.

أولاً، يقيس النظام عدد العناصر التي يتم عرضها. تحتوي كل طريقة عرض وتنسيق على dataمحددة تصف حجم العنصر على الشاشة. يمكن أن يكون لبعض طرق العرض حجمًا محدّدًا، بينما يكون حجم طرق العرض الأخرى متوافقًا مع حجم حاوية التنسيق الرئيسي.

ثانيًا، يعرض النظام عناصر العرض. بعد أن يحسب النظام أحجام مشاهدات الأطفال، يمكنه المتابعة بتنسيق المشاهدات وتحديد أحجامها ووضعها على الشاشة.

لا يُجري النظام عمليات القياس والتنسيق للعروض المراد رسمها فقط، بل أيضًا للترتيبات التسلسلية الرئيسية لهذه العروض، وصولاً إلى العروض الجذرية.

عندما تكون هذه الشريحة كبيرة

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

قد يتسبّب الرمز الذي أضفته إلى onLayout(boolean, int, int, int, int) أو onMeasure(int, int) أيضًا في حدوث مشاكل في الأداء. يمكن أن تساعدك أداتا Traceview وSystrace في فحص ملفّات تتبُّع استدعاء الدوال البرمجية لتحديد المشاكل التي قد تواجهها الرموز البرمجية.

رسم

تُحوّل مرحلة الرسم عمليات عرض العناصر، مثل رسم خلفية أو رسم نص، إلى تسلسل من أوامر الرسم الأصلية. ويلتقط النظام هذه الأوامر في قائمة عرض.

يسجل شريط الرسم مقدار الوقت الذي يستغرقه إكمال التقاط الأوامر في قائمة العرض، لجميع طرق العرض التي يلزم تحديثها على الشاشة هذا الإطار. ينطبق الوقت الذي تم قياسه على أي رمز أضفته إلى عناصر واجهة المستخدم في تطبيقك. من أمثلة هذه الرموز onDraw() وdispatchDraw() وdraw ()methods المختلفة التي تنتمي إلى الفئات الفرعية للفئة Drawable.

عندما تكون هذه الشريحة كبيرة

بعبارات مبسّطة، يمكنك فهم هذا المقياس على أنّه يعرض المدة التي استغرقها تنفيذ جميع الطلبات الموجَّهة إلى onDraw() لكل ملف شخصي تم إلغاء صلاحيته. ويشمل هذا القياس أي وقت يتم قضاؤه في توجيه أوامر الرسم إلى الأطفال والمواد التي قد تكون موجودة. لهذا السبب، عندما تلاحظ ارتفاعًا في عدد المشاهدات، قد يكون السبب أنّ مجموعة من المشاهدات قد أصبحت فجأة غير صالحة. يتطلّب إلغاء الصلاحية إعادة إنشاء قوائم العرض الخاصة بطُرق العرض. بدلاً من ذلك، قد يكون وقت التحميل الطويل ناتجًا عن بعض طرق الاطِّلاع المخصّصة التي تتضمّن منطقًا معقدًا للغاية في onDraw().

المزامنة/التحميل

يمثّل مقياس "المزامنة والتحميل" الوقت الذي يستغرقه نقل عناصر ملفات الأشكال المصغرة من ذاكرة وحدة المعالجة المركزية إلى ذاكرة وحدة معالجة الرسومات أثناء عرض اللقطة الحالية.

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

ملاحظة: على أجهزة Lollipop، تظهر هذه المرحلة باللون البنفسجي.

عندما تكون هذه الشريحة كبيرة

يجب أن تكون جميع موارد اللقطة موجودة في ذاكرة وحدة معالجة الرسومات قبل أن تتمكّن من استخدامها لرسم اللقطة. هذا يعني أنّ القيمة العالية لهذا المقياس قد تعني عددًا كبيرًا من عمليات تحميل الموارد الصغيرة أو عددًا صغيرًا من الموارد الكبيرة جدًا. هناك حالة شائعة وهي عندما يعرض أحد التطبيقات صورة نقطية واحدة على مقربة من حجم الشاشة. هناك حالة أخرى عندما يعرض التطبيق عددًا كبيرًا من الصور المصغرة.

لتصغير هذا الشريط، يمكنك استخدام أساليب مثل:

  • التأكّد من أنّ درجات دقة الصور الممسوحة ضوئيًا ليست أكبر بكثير من الحجم الذي سيتم عرضها به على سبيل المثال، يجب أن يتجنّب تطبيقك عرض صورة بحجم 1024×1024 كصورة بحجم 48×48.
  • الاستفادة من prepareToDraw() لتحميل خريطة بتر قبل المزامنة بشكل غير متزامن قبل مرحلة المزامنة التالية

أوامر المشاكل

يمثل قسم أوامر المشكلة الوقت المستغرق لإصدار جميع الأوامر اللازمة لرسم قوائم العرض على الشاشة.

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

تستغرق هذه العملية بعض الوقت، لأنّ النظام يُجري عملية التحويل والاقتصاص النهائية لكلّ أمر قبل إرسال الأمر إلى وحدة معالجة الرسومات. بعد ذلك، تظهر عملية معالجة إضافية على جانب وحدة معالجة الرسومات، والتي تحسب الأوامر النهائية. وتشمل هذه الطلبات عمليات التحويل النهائية والقطع الإضافي.

عندما تكون هذه الشريحة كبيرة

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

Kotlin

for (i in 0 until 1000) {
    canvas.drawPoint()
}

Java

for (int i = 0; i < 1000; i++) {
    canvas.drawPoint()
}

أكثر تكلفة بكثير من:

Kotlin

canvas.drawPoints(thousandPointArray)

Java

canvas.drawPoints(thousandPointArray);

لا يوجد دائمًا ارتباط 1:1 بين إصدار الأوامر ورسم قوائم العرض فعليًا. على عكس أوامر المشاكل التي تسجّل الوقت المستغرق لإرسال أوامر الرسم إلى وحدة معالجة الرسومات، يمثّل مقياس الرسم الوقت الذي استغرقه تسجيل الأوامر الصادرة في قائمة العرض.

ويعود هذا الاختلاف إلى أنّه يتم تخزين قوائم العرض مؤقتًا في ذاكرة التخزين المؤقت للنظام كلما أمكن ذلك. ونتيجةً لذلك، هناك مواقف يتطلّب فيها التمرير أو التحويل أو الرسم المتحرك من النظام إعادة إرسال قائمة عرض، ولكن ليس من الضروري إعادة بنائها فعليًا—عن طريق إعادة صياغة أوامر الرسم—من البداية. ونتيجةً لذلك، يمكنك أن ترى شريط "أوامر المشاكل" العالي بدون ظهور شريط رسم أوامر عالٍ.

الموارد الاحتياطية للمعالجة أو التبديل

بعد أن ينتهي نظام التشغيل Android من إرسال كل قائمة العروض إلى وحدة معالجة الرسومات، يُصدر النظام أمرًا نهائيًا لإعلام برنامج تشغيل الرسومات بأنّه انتهى من اللقطة الحالية. في هذه المرحلة، يمكن للسائق أخيرًا عرض الصورة المعدَّلة على الشاشة.

عندما تكون هذه الشريحة كبيرة

من المهم معرفة أنّ وحدة معالجة الرسومات تعمل بالتوازي مع وحدة المعالجة المركزية (CPU). ترسم مشكلات نظام Android الأوامر إلى وحدة معالجة الرسومات، ثم تنتقل إلى المهمة التالية. تقرأ وحدة معالجة الرسومات أوامر الرسم هذه من قائمة انتظار وتعالجها.

في الحالات التي تُصدر فيها وحدة المعالجة المركزية (CPU) الأوامر بشكل أسرع من استهلاك وحدة معالجة الرسومات (GPU) لها، يمكن أن تمتلئ قائمة الانتظار للاتصالات بين المعالجَين. عندما يحدث هذا، تتجمع وحدة المعالجة المركزية (CPU) وتنتظر حتى تكون هناك مساحة في قائمة الانتظار لوضع الأمر التالي. وتظهر حالة الانتظار الكامل هذه غالبًا أثناء مرحلة Swap Buffers (محفظات التبديل المؤقتة) لأنّه عند هذه النقطة، تم إرسال أوامر إطار كامل.

يكمن مفتاح الحد من هذه المشكلة في تقليل تعقيد العمل الذي يتم على وحدة معالجة الرسومات، وذلك بطريقة مشابهة لما ستفعله في مرحلة &quot;إصدار الأوامر&quot; .

متنوعة

بالإضافة إلى الوقت الذي يستغرقه نظام العرض لتنفيذ عمله، تتم تنفيذ مجموعة إضافية من الأعمال في سلسلة المهام الرئيسية والتي ليس لها أي علاقة بالعرض. ويتم تسجيل الوقت الذي يستغرقه هذا العمل على أنّه وقت متعدّد الاستخدامات. يمثل الوقت المتنوع عمومًا العمل الذي قد يحدث في سلسلة واجهة المستخدم بين إطارين متتاليين للعرض.

عندما تكون هذه الشريحة كبيرة

إذا كانت هذه القيمة مرتفعة، من المرجّح أن يحتوي تطبيقك على عمليات استدعاء أو نوايا أو أعمال أخرى من المفترض أن تتم في سلسلة محادثات أخرى. يمكن أن تقدّم أدوات مثل تتبُّع Method أو Systraceاطلاعًا على المهام التي يتم تنفيذها على السلسلة الرئيسية. ويمكن أن تساعدك هذه المعلومات في استهداف تحسينات الأداء.