فهم تتبُّع النظام

systrace هي الأداة الأساسية لتحليل أداء جهاز Android. ومع ذلك، فإنه في الحقيقة برنامج التفاف حول أدوات أخرى. برنامج تضمين من جهة المضيف حول atrace، وهو الملف التنفيذي من جهة الجهاز الذي يتحكّم في مساحة المستخدم عملية التتبّع وإعداد ftrace وآلية التتبّع الأساسية في Linux النواة (النواة). يستخدم systrace السمة atrace لتمكين التتبع، ثم يقرأ المخزن المؤقت ftrace ويعمل على التفاف كل ذلك في عارض HTML مستقل. (على الرغم من دعم النواة الأحدث لفلتر حزم بيركيلي المحسّن لنظام التشغيل Linux (eBPF)، المستندات التالية يتعلق بالنواة 3.18 (بدون eFPF) بما أنّ ذلك المستخدم في هواتف Pixel أو Pixel كبير جدًا).

ويملكه فريق Google Android وGoogle Chrome مفتوحة المصدر كجزء من مشروع Catapult: ضِمن بالإضافة إلى systrace، يشتمل Catapult على أدوات مساعدة أخرى مفيدة. على سبيل المثال: يحتوي ftrace على ميزات أكثر من التي يمكن تفعيلها مباشرةً بواسطة سجل النظام أو atrace يتضمن بعض الوظائف المتقدمة التي تساهم في تصحيح أخطاء الأداء المشكلات. (تتطلب هذه الميزات الوصول إلى الجذر، وغالبًا ما تحتاج إلى نواة جديدة.)

تنفيذ عملية تتبُّع النظام

عند تصحيح عدم الاستقرار على Pixel/Pixel XL، ابدأ بما يلي: :

./systrace.py sched freq idle am wm gfx view sync binder_driver irq workq input -b 96000

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

ضع في اعتبارك أن كل حدث يتم تنفيذه أثناء عملية تتبُّع النظام بسبب مشكلة في وحدة المعالجة المركزية (CPU)

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

مثال: إطار العمل

يصف هذا المثال تتبع نظام لمسار عادي لواجهة المستخدم. للمتابعة باستخدام المثال، نزِّل الملف المضغوط للتتبُّعات (والذي يتضمن أيضًا آثارًا أخرى تتم الإشارة إليها في هذا القسم)، فقم بفك ضغط الملف، وافتح ملف systrace_tutorial.html في المتصفّح. التحذيرات أن تتبع النظام هذا ملف كبير؛ ما لم تستخدم النظام في أعمالك اليومية فمن المحتمل أن يكون ذلك أكبر بكثير من المعلومات التي حققتها أي أثر واحد من قبل.

للحصول على عبء عمل دوري ومتسق مثل TouchLatency، يتم يحتوي على ما يلي:

  1. تعمل أداة EventThread في SurfaceFlinger على تنشيط سلسلة واجهة المستخدم في التطبيق للإشارة إلى أنّه قد حان الوقت. لعرض إطار جديد.
  2. يعرض التطبيق إطارًا في سلسلة واجهة المستخدم وRenderThread وhwuiTasks باستخدام وحدة المعالجة المركزية موارد وحدة معالجة الرسومات هذا هو الجزء الأكبر من السعة التي يتم إنفاقها على واجهة المستخدم.
  3. يرسل التطبيق الإطار المعروض إلى SurfaceFlinger باستخدام مادة ربط، ثم ينتقل SurfaceFlinger إلى وضع السكون.
  4. يؤدي استخدام EventThread الثاني في SurfaceFlinger إلى تنشيط SurfaceFlinger. والتكوين وإخراج العرض. إذا اكتشف SurfaceFlinger أنّه لا يمكن إجراء عند الانتهاء، يعود إلى وضع السكون.
  5. يتعامل SurfaceFlinger مع التركيبة باستخدام معدّات Compose (HWC) أو معدّات. Composer 2 (HWC2) أو GL. تركيب HWC/HWC2 هي أسرع وأقل طاقة، ولكن لها قيود اعتمادًا على النظام على الشريحة (SoC). يستغرق ذلك عادةً من 4 إلى 6 ملّي ثانية تقريبًا، ولكن قد يتداخل مع الخطوة 2 لأنّ Android دائمًا ما يتم التخزين المؤقت ثلاث مرات. (على الرغم من التخزين المؤقت ثلاث مرات للتطبيقات دائمًا، هناك قد يكون هناك إطار واحد فقط في انتظار المراجعة في SurfaceFlinger، ما يجعله يظهر مماثلة للتخزين المؤقت المزدوج).
  6. تقوم SurfaceFlinger بإرسال المخرجات النهائية لعرضها باستخدام برنامج تشغيل البائع ثم يعود إلى وضع السكون، في انتظار استيقاظ EventThread.

لنتصفح الإطار الذي يبدأ عند 15409 ملي ثانية:

مسار واجهة المستخدم العادي مع تشغيل EventThread
الشكل 1. مسار واجهة المستخدم العادية، وEventThread قيد التشغيل

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

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

لعرض سبب النوم غير المنقطع (متاح من sched_blocked_reason نقطة تتبُّع)، اختَر الرمز الأحمر غير القابل للمقاطعة شريحة النوم.

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

سلسلة واجهة المستخدم لـ TouchLatency
الشكل 2. سلسلة واجهة المستخدم لـ TouchLatency

يوضح الشكل 2 أن مؤشر ترابط واجهة مستخدم TouchLatency قد تم تنشيطه بواسطة tid 6843، والذي يتجاوب مع EventThread. يتم تنشيط سلسلة واجهة المستخدم وعرض إطار عليها وإدخالها في قائمة الانتظار. لكي يستهلكها SurfaceFlinger.

يتم تنشيط سلسلة واجهة المستخدم وعرض إطار عليها وإدخالها في قائمة انتظار ليستخدمها SurfaceFlinger.
الشكل 3. يتم تنشيط سلسلة واجهة المستخدم وعرض إطار عليها وتضمينها في قائمة انتظار. كي تستهلكه SurfaceFlinger

في حال تفعيل علامة binder_driver في عملية تتبُّع، يمكنك اختيار المعاملات لعرض معلومات عن جميع العمليات المتضمنة في تلك معاملة.

الشكل 4. معاملة دمج

يبيّن الشكل 4 أنه عند 15,423.65 ملّي ثانية Binder:6832_1 في SurfaceFlinger يصبح يمكن تنفيذه بسبب tid 9579، وهو RenderThread من TouchLatency. يمكنك أيضًا ستظهر لك playlistBuffer على جانبَي معاملة أداة الربط.

أثناء PendingBuffer على جانب SurfaceFlinger، يستنِد عدد طلبات البحث الإطارات من TouchLatency تتراوح من 1 إلى 2.

تتراوح الإطارات المعلّقة من 1 إلى 2.
الشكل 5. تتراوح الإطارات المعلّقة من 1 إلى 2.

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

بعد فترة وجيزة، يتم استيقاظ سلسلة محادثات SurfaceFlinger الرئيسية من خلال حدث EventThread الثاني، وبالتالي يمكنه إخراج الإطار المعلق القديم على الشاشة:

تم تنشيط سلسلة التعليمات الرئيسية في SurfaceFlinger بواسطة EventThread الثاني.
الشكل 6. يتم تنشيط سلسلة التعليمات الرئيسية في SurfaceFlinger بثانية واحدة. سلسلة محادثات

يغلق SurfaceFlinger أولاً المخزن المؤقت المعلق القديم، مما يتسبب في في انتظار انخفاض عدد الموارد الاحتياطية من 2 إلى 1.

تثبيت SurfaceFlinger أولاً بالمخزن المؤقت القديم الذي ينتظر المراجعة
الشكل 7. تثبيت SurfaceFlinger أولاً بأول معلّق المورد الاحتياطي

بعد تثبيت المزلاج، يقوم SurfaceFlinger بإعداد التركيبة وإرسال الإطار الأخير إلى الشاشة. (يتم تفعيل بعض هذه الأقسام كجزء من mdss، لذا قد لا يتم تضمينها في المنظومة على الرقاقة (SoC).)

يقوم SurfaceFlinger بإعداد التركيبة وإرسال الإطار النهائي.
الشكل 8. يقوم SurfaceFlinger بإعداد التركيبة وإرسال الإطار الأخير

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

يتم تنشيط mdss_fb0 على وحدة المعالجة المركزية 0
الشكل 9. يتم تنشيط mdss_fb0 على وحدة المعالجة المركزية 0.

يستيقظ "mdss_fb0" ويجري لفترة قصيرة ويدخل في نوم لا تقاطع ثم يستيقظ مرة أخرى.

مثال: إطار لا يعمل

يصف هذا المثال تتبُّع النظام المستخدَم لتصحيح أخطاء عدم استقرار Pixel/Pixel XL. إلى ومتابعة المثال، تنزيل ملف zip ملف آثار الأنشطة (يشمل ذلك آثار الأنشطة الأخرى المُشار إليها في هذا )، ثم فك ضغط الملف، ثم افتح ملف systrace_tutorial.html في المتصفح.

عند فتح سجل النظام، سيظهر لك شيء مثل هذا:

يعمل TouchLatency على هاتف Pixel XL مع تفعيل معظم الخيارات.
الشكل 10. TouchLatency يعمل على Pixel XL (معظم الخيارات مُفعَّل، بما في ذلك نقاط تتبُّع mdss وkgsl)

عند البحث عن البيانات غير القابلة للاكتشاف، تحقق من صف FrameFound ضمن SurfaceFlinger. تحسين جودة الحياة يوفره HWC2. عند العرض للأجهزة الأخرى، فقد لا يكون الصف FramePause موجودًا إذا كان الجهاز لا يستخدم HWC2. في أيّ منهما فإن FrameBack مرتبط بـ SurfaceFlinger مفقودًا بيئات تشغيل منتظمة للغاية وعدد غير محدود من المخزن المؤقت المعلَّق للتطبيق (com.prefabulated.touchlatency) في vsync.

ارتباط Frame الإضافي بـ SurfaceFlinger
الشكل 11. ارتباط Frame الإضافي بـ SurfaceFlinger

يعرض الشكل 11 إطارًا مفقودًا عند 15598.29 ملّي ثانية. استيقظ SurfaceFlinger لفترة وجيزة في فاصل vsync والرجوع إلى وضع السكون بدون القيام بأي عمل، مما يعني تبيّن لشركة SurfaceFlinger أنّه لا يجب محاولة إرسال إطار إلى الشاشة. مرة أخرى. ما السبب؟

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

يستيقظ SurfaceFlinger وينتقل إلى النوم فورًا
الشكل 12. يستيقظ SurfaceFlinger وينتقل فورًا إلى نوم

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

بما أنّه قد تم تفعيل نقطتَي التتبّع mdss وsync، يمكننا الحصول على معلومات عن الحدود (مشتركة بين برنامج تشغيل الشاشة SurfaceFlinger) تتحكم في وقت إرسال الإطارات إلى الشاشة. تم سرد هذه السياجات ضمن mdss_fb0_retire، الذي يشير إلى حالة ظهور إطار على الشاشة. يتم توفير هذه السياج جزء من فئة التتبع sync. أي السياجات تتوافق مع تعتمد أحداث معيّنة في SurfaceFlinger على رمز SOC وحزمة برنامج التشغيل، لذلك أن تعمل مع مورّد SOC لفهم معنى فئات السياج في آثار.

أسوار التقاعد
الشكل 13. mdss_fb0_سياج التقاعد

يعرض الشكل 13 إطارًا تم عرضه لمدة 33 ملي ثانية، وليس لمدة 16.7 ملي ثانية كما هو متوقع. في منتصف تلك الشريحة، يجب استبدال الإطار بإطار جديد. لكنه لم يكن كذلك. اعرض الإطار السابق وابحث عن أي شيء.

إطار سابق لإطار تم ضبط الإعدادات
الشكل 14. إطار سابق لإطار تم ضبط الإعدادات

يوضح الشكل 14 أن الإطار 14.482 ملي ثانية. وكانت مدة المقطع المقطوع من إطارين 33.6 ملي ثانية، وهو ما نتوقعه تقريبًا لإطارين (نعرضه عند 60 هرتز و16.7 ملي ثانية). لكل إطار، وهو أمر قريب). ولكن 14.482 ملي ثانية لا تقترب من 16.7 ملي ثانية على الإطلاق، مما يشير إلى وجود خطأ كبير في ممر العرض.

عليك التحقّق بالضبط من النقطة التي ينتهي عندها هذا السياج لتحديد ما يتحكم فيه.

التحقيق في نهاية السياج
الشكل 15. التحقيق في نهاية السياج

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

راجِع الإطار السابق لتحديد ما إذا كان ذلك قد ساهم في ذلك. غير مستقر يمكن أن تتراكم بمرور الوقت ويؤدي في النهاية إلى تجاوز الموعد النهائي.

الإطار السابق
الشكل 16. الإطار السابق

لا يظهر الخط القابل للتشغيل على kworker لأنّ المشاهد يحوّله باللون الأبيض عند تحديده، لكن الإحصاءات تروي القصة: 2.3 مللي ثانية من أداة الجدولة التأخير لجزء من المسار الحرج لمسار العرض سيئ. قبل المتابعة، أصلح التأخير الذي يتمثل في نقل هذا الجزء من عرض المسار الحرج للمسار من قائمة انتظار العمل (والذي يعمل كـ سلسلة محادثات CFS واحدة (SCHED_OTHER)) إلى SCHED_FIFO مخصّص kthread تحتاج هذه الدالة إلى ضمانات التوقيت بأن قوائم انتظار العمل لا يمكن (أو لا إلى توفيره.

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

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