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

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

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

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

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

الرسم البياني لعرض GPU
الشكل 1. الرسم البياني لعرض GPU

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

وسيلة إيضاح الرسم البياني لعرض GPU
الشكل 2. شرح بياني لرسم مخطط عرض GPU

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

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

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

التعامل مع البيانات المُدخَلة

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

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

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

قد يظهر أيضًا في هذه المرحلة التمرير سريعًا خلال LazyColumn أو LazyRow. وبعد أن يتم تصنيف لمسة المستخدم على أنّها تمرير سريع، تستهلك القائمة الكسولة أحداث اللمس لإنشاء العناصر وتنسيقها بشكل ديناميكي. إذا كان تطبيقك ينفّذ عملية مخصّصة استجابةً لتغييرات موضع التمرير، من المهم أن تكون هذه العملية بأسرع ما يمكن لتجنُّب فقدان اللقطات. يمكن أن تساعدك أدوات إنشاء الملفات الشخصية، مثل CPU Profiler في "استوديو Android" أو Perfetto، في إجراء المزيد من التحقيقات. لمزيد من المعلومات، اطّلِع على نظرة عامة على تتبُّع النظام.

الصور المتحركة

تعرض مرحلة الصور المتحركة المدة التي استغرقتها عملية تقييم جميع حالات الصور المتحركة التي كانت تعمل في هذا الإطار. بعض واجهات برمجة التطبيقات الشائعة للرسوم المتحركة في Compose هي animate*AsState وTransition وAnimatable. بالإضافة إلى ذلك، يتم تشغيل Recomposer خلال هذه المرحلة لمعالجة التغييرات في حالة اللقطة وتعديل عمليات الإنشاء. وهذا يعني أنّ تكلفة إعادة التركيب غالبًا ما تظهر مباشرةً في مرحلة الصورة المتحركة.

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

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

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

قياس

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

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

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

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

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

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

استخدِم أداة CPU Profiler في "استوديو Android" أو Perfetto لفحص عمليات التنسيق وتحديد المشاكل التي تؤدي إلى بطء الأداء. لمزيد من المعلومات، راجِع نظرة عامة على تتبُّع نشاط النظام.

الرسم

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

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

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

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

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

تحميل

يمثّل مقياس التحميل الوقت المستغرَق لنقل عناصر الصور النقطية من ذاكرة وحدة المعالجة المركزية إلى ذاكرة وحدة معالجة الرسومات خلال الإطار الحالي.

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

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

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

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

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

  • التأكّد من أنّ دقة الصور النقطية ليست أكبر بكثير من الحجم الذي سيتم عرضها به على سبيل المثال، تجنَّب عرض صورة بحجم 1024x1024 كصورة بحجم 48x48.
  • الاستفادة من المكتبات الحديثة، مثل Coil لتحميل صورة نقطية مسبقًا بشكل غير متزامن قبل مرحلة المزامنة التالية

إصدار الأوامر

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

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

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

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

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

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

تكون تكلفة إصدارها أعلى بكثير من:

canvas.drawPoints(thousandPointArray)

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

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

تبديل المخازن المؤقتة

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

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

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

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

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

متنوعة

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

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

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