सिस्ट्रेस को समझना

एंड्रॉइड डिवाइस के प्रदर्शन का विश्लेषण करने के लिए सिस्ट्रेस प्राथमिक उपकरण है। हालांकि, यह वास्तव में अन्य उपकरणों के आसपास एक आवरण है। यह एट्रेस के आस-पास होस्ट-साइड रैपर है, डिवाइस-साइड निष्पादन योग्य है जो यूजरस्पेस ट्रेसिंग को नियंत्रित करता है और ftrace सेट करता है, और लिनक्स कर्नेल में प्राथमिक ट्रेसिंग तंत्र है। सिस्ट्रेस ट्रेसिंग को सक्षम करने के लिए एट्रेस का उपयोग करता है, फिर फ़्रेट्रेस बफर को पढ़ता है और इसे एक स्व-निहित HTML व्यूअर में लपेटता है। (जबकि नए कर्नेल में Linux एन्हांस्ड बर्कले पैकेट फ़िल्टर (eBPF) के लिए समर्थन है, निम्नलिखित दस्तावेज़ 3.18 कर्नेल (कोई eFPF) से संबंधित नहीं है, जैसा कि Pixel/Pixel XL पर उपयोग किया गया था।)

systrace Google Android और Google Chrome टीमों के स्वामित्व में है और Catapult प्रोजेक्ट के हिस्से के रूप में खुला स्रोत है। सिस्ट्रेस के अलावा, गुलेल में अन्य उपयोगी उपयोगिताएँ शामिल हैं। उदाहरण के लिए, ftrace में सिस्ट्रेस या एट्रेस द्वारा सीधे सक्षम की तुलना में अधिक सुविधाएँ हैं और इसमें कुछ उन्नत कार्यक्षमता शामिल हैं जो प्रदर्शन समस्याओं को डीबग करने के लिए महत्वपूर्ण हैं। (इन सुविधाओं के लिए रूट पहुंच और अक्सर एक नए कर्नेल की आवश्यकता होती है।)

रनिंग सिस्ट्रेस

पिक्सेल/पिक्सेल एक्सएल पर जिटर डीबग करते समय, निम्न आदेश से प्रारंभ करें:

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

GPU और डिस्प्ले पाइपलाइन गतिविधि के लिए आवश्यक अतिरिक्त ट्रेसपॉइंट के साथ संयुक्त होने पर, यह आपको स्क्रीन पर प्रदर्शित उपयोगकर्ता इनपुट से फ्रेम तक ट्रेस करने की क्षमता देता है। घटनाओं को खोने से बचने के लिए बफर आकार को कुछ बड़े पर सेट करें (क्योंकि बड़े बफर के बिना कुछ सीपीयू में ट्रेस में कुछ बिंदु के बाद कोई घटना नहीं होती है)।

सिस्ट्रेस से गुजरते समय, ध्यान रखें कि प्रत्येक घटना सीपीयू पर किसी चीज से शुरू होती है

क्योंकि सिस्ट्रेस ftrace के ऊपर बनाया गया है और ftrace CPU पर चलता है, CPU पर कुछ ftrace बफ़र लिखना चाहिए जो हार्डवेयर परिवर्तनों को लॉग करता है। इसका मतलब यह है कि यदि आप इस बारे में उत्सुक हैं कि डिस्प्ले बाड़ ने राज्य क्यों बदल दिया, तो आप देख सकते हैं कि सीपीयू पर इसके संक्रमण के सटीक बिंदु पर क्या चल रहा था (सीपीयू पर चलने वाली कोई चीज लॉग में उस बदलाव को ट्रिगर करती है)। यह अवधारणा सिस्ट्रेस का उपयोग करके प्रदर्शन का विश्लेषण करने की नींव है।

उदाहरण: वर्किंग फ्रेम

यह उदाहरण सामान्य UI पाइपलाइन के लिए एक सिस्ट्रेस का वर्णन करता है। उदाहरण के साथ अनुसरण करने के लिए, ट्रेस की ज़िप फ़ाइल डाउनलोड करें (जिसमें इस अनुभाग में संदर्भित अन्य ट्रेस भी शामिल हैं), फ़ाइल को अनज़िप करें, और अपने ब्राउज़र में systrace_tutorial.html फ़ाइल खोलें। सावधान रहें कि यह सिस्ट्रेस एक बड़ी फ़ाइल है; जब तक आप अपने दिन-प्रतिदिन के काम में सिस्ट्रेस का उपयोग नहीं करते हैं, तब तक यह बहुत अधिक जानकारी के साथ एक बहुत बड़ा ट्रेस होने की संभावना है, जो आपने पहले कभी एक ट्रेस में नहीं देखा है।

एक सुसंगत, आवधिक कार्यभार जैसे TouchLatency के लिए, UI पाइपलाइन में निम्नलिखित शामिल हैं:

  1. सरफेसफ्लिंगर में EventThread ऐप UI थ्रेड को जगाता है, यह संकेत देता है कि यह एक नया फ्रेम रेंडर करने का समय है।
  2. ऐप CPU और GPU संसाधनों का उपयोग करते हुए UI थ्रेड, RenderThread और hwuiTasks में एक फ्रेम प्रस्तुत करता है। यह UI के लिए खर्च की गई क्षमता का बड़ा हिस्सा है।
  3. ऐप बाइंडर का उपयोग करके रेंडर किए गए फ्रेम को सर्फेसफ्लिंगर को भेजता है, फिर सर्फेसफ्लिंगर सो जाता है।
  4. सर्फेसफ्लिंगर में दूसरा इवेंट थ्रेड कंपोजिशन और डिस्प्ले आउटपुट को ट्रिगर करने के लिए सर्फेसफ्लिंगर को जगाता है। यदि सर्फेसफ्लिंगर यह निर्धारित करता है कि कोई काम नहीं करना है, तो वह वापस सो जाता है।
  5. सरफेसफ्लिंगर हार्डवेयर कम्पोज़र (HWC)/हार्डवेयर कम्पोज़र 2 (HWC2) या GL का उपयोग करके संरचना को संभालता है। HWC/HWC2 संरचना तेज और कम शक्ति वाली है लेकिन एक चिप (SoC) पर सिस्टम के आधार पर इसकी सीमाएं हैं। यह आमतौर पर ~ 4-6 एमएस लेता है, लेकिन चरण 2 के साथ ओवरलैप हो सकता है क्योंकि एंड्रॉइड ऐप्स हमेशा ट्रिपल बफर होते हैं। (जबकि ऐप्स हमेशा ट्रिपल बफर होते हैं, सर्फेसफ्लिंगर में केवल एक लंबित फ्रेम प्रतीक्षा कर सकता है, जो इसे डबल बफरिंग के समान दिखता है।)
  6. सर्फेसफ्लिंगर विक्रेता ड्राइवर के साथ प्रदर्शित करने के लिए अंतिम आउटपुट भेजता है और इवेंट थ्रेड वेकअप की प्रतीक्षा में वापस सो जाता है।

आइए 15409 एमएस से शुरू होने वाले फ्रेम के माध्यम से चलते हैं:

EventThread के साथ सामान्य UI पाइपलाइन चल रही है
चित्र 1. सामान्य UI पाइपलाइन, EventThread चल रहा है

चित्र 1 सामान्य फ्रेम से घिरा एक सामान्य फ्रेम है, इसलिए यह समझने के लिए एक अच्छा प्रारंभिक बिंदु है कि UI पाइपलाइन कैसे काम करती है। TouchLatency के लिए UI थ्रेड पंक्ति में अलग-अलग समय पर अलग-अलग रंग शामिल हैं। बार्स धागे के लिए अलग-अलग राज्यों को दर्शाते हैं:

  • ग्रे । सोना।
  • नीला। रननेबल (यह चल सकता है, लेकिन शेड्यूलर ने इसे अभी तक चलाने के लिए नहीं चुना है)।
  • हरा। सक्रिय रूप से चल रहा है (अनुसूचक सोचता है कि यह चल रहा है)।
  • लाल। निर्बाध नींद (आमतौर पर कर्नेल में लॉक पर सोना)। I/O लोड का संकेत हो सकता है। प्रदर्शन समस्याओं को डीबग करने के लिए अत्यंत उपयोगी।
  • संतरा। I/O लोड के कारण निर्बाध नींद।

निर्बाध नींद का कारण देखने के लिए ( sched_blocked_reason ट्रेसपॉइंट से उपलब्ध), लाल निर्बाध स्लीप स्लाइस का चयन करें।

जबकि EventThread चल रहा है, TouchLatency के लिए UI थ्रेड चलाने योग्य हो जाता है। यह देखने के लिए कि इसने क्या जगाया, नीले अनुभाग पर क्लिक करें।

TouchLatency के लिए UI थ्रेड
चित्र 2. TouchLatency के लिए UI थ्रेड

चित्र 2 दिखाता है कि TouchLatency UI थ्रेड को 6843 tid द्वारा जगाया गया था, जो EventThread से मेल खाती है। यूआई थ्रेड जागता है, एक फ्रेम प्रस्तुत करता है, और इसे सर्फेसफ्लिंगर के उपभोग के लिए संलग्न करता है।

यूआई थ्रेड जागता है, एक फ्रेम प्रस्तुत करता है, और इसे सर्फेसफ्लिंगर के उपभोग के लिए संलग्न करता है
चित्रा 3. यूआई थ्रेड जागता है, एक फ्रेम प्रस्तुत करता है, और इसे सर्फेसफ्लिंगर के उपभोग के लिए संलग्न करता है

यदि ट्रेस में binder_driver टैग सक्षम है, तो आप उस लेन-देन में शामिल सभी प्रक्रियाओं की जानकारी देखने के लिए एक बाइंडर लेनदेन का चयन कर सकते हैं।

चित्रा 4. बाइंडर लेनदेन

चित्र 4 से पता चलता है कि, 15,423.65 एमएस बाइंडर: 6832_1 सर्फेसफ्लिंगर में टिड 9579 के कारण चलने योग्य हो जाता है, जो कि टचलेटेंसी का रेंडरथ्रेड है। आप बाइंडर लेनदेन के दोनों किनारों पर क्यूबफ़र भी देख सकते हैं।

सरफेसफ्लिंगर की तरफ क्यूबफर के दौरान, टचलेटेंसी से लंबित फ्रेम की संख्या 1 से 2 हो जाती है।

लंबित फ़्रेम 1 से 2 . तक जाते हैं
चित्र 5. लंबित फ़्रेम 1 से 2 . तक जाते हैं

चित्र 5 ट्रिपल बफ़रिंग दिखाता है, जहाँ दो पूर्ण फ़्रेम हैं और ऐप एक तिहाई रेंडर करना शुरू करने वाला है। ऐसा इसलिए है क्योंकि हमने पहले ही कुछ फ़्रेम गिरा दिए हैं, इसलिए ऐप आगे गिराए गए फ़्रेम से बचने के लिए एक के बजाय दो लंबित फ़्रेम रखता है।

इसके तुरंत बाद, सर्फेसफ्लिंगर का मुख्य धागा एक दूसरे EventThread द्वारा जगाया जाता है ताकि यह पुराने लंबित फ्रेम को डिस्प्ले में आउटपुट कर सके:

सर्फेसफ्लिंगर का मुख्य धागा एक दूसरे EventThread द्वारा जगाया जाता है
चित्र 6. सर्फेसफ्लिंगर का मुख्य धागा एक दूसरे EventThread द्वारा जगाया जाता है

सरफेसफ्लिंगर पहले पुराने पेंडिंग बफर को लैच करता है, जिससे पेंडिंग बफर काउंट 2 से घटकर 1 हो जाता है।

सरफेसफ्लिंगर पहले पुराने लंबित बफर पर लैच करता है
चित्रा 7. भूतलफ्लिंगर पहले पुराने लंबित बफर पर लेट जाता है

बफ़र को लैच करने के बाद, SurfaceFlinger कंपोज़िशन सेट करता है और अंतिम फ़्रेम को डिस्प्ले पर सबमिट करता है। (इनमें से कुछ अनुभाग mdss ट्रेसपॉइंट के भाग के रूप में सक्षम हैं, इसलिए हो सकता है कि वे आपके SoC में शामिल न हों।)

सरफेसफ्लिंगर कंपोजिशन सेट करता है और फाइनल फ्रेम सबमिट करता है
चित्रा 8. सर्फेसफ्लिंगर रचना सेट करता है और अंतिम फ्रेम जमा करता है

अगला, mdss_fb0 CPU 0 पर जागता है। mdss_fb0 डिस्प्ले के लिए एक रेंडर किए गए फ्रेम को आउटपुट करने के लिए डिस्प्ले पाइपलाइन का कर्नेल थ्रेड है। हम mdss_fb0 को ट्रेस में अपनी पंक्ति के रूप में देख सकते हैं (देखने के लिए नीचे स्क्रॉल करें)।

mdss_fb0 CPU पर जागता है 0
चित्र 9. mdss_fb0 CPU पर जागता है 0

mdss_fb0 जागता है, थोड़ी देर चलता है, निर्बाध नींद में प्रवेश करता है, फिर जागता है।

उदाहरण: गैर-कार्यशील फ्रेम

यह उदाहरण पिक्सेल/पिक्सेल एक्सएल जिटर को डीबग करने के लिए उपयोग किए जाने वाले सिस्ट्रेस का वर्णन करता है। उदाहरण के साथ अनुसरण करने के लिए, ट्रेस की ज़िप फ़ाइल डाउनलोड करें (जिसमें इस अनुभाग में संदर्भित अन्य ट्रेस शामिल हैं), फ़ाइल को अनज़िप करें, और अपने ब्राउज़र में systrace_tutorial.html फ़ाइल खोलें।

जब आप सिस्ट्रेस खोलते हैं, तो आपको कुछ इस तरह दिखाई देगा:

अधिकांश विकल्पों के साथ Pixel XL पर चलने वाली TouchLatency सक्षम है
चित्र 10. Pixel XL पर चलने वाली TouchLatency (अधिकांश विकल्प सक्षम हैं, जिनमें mdss और kgsl ट्रेसपॉइंट शामिल हैं)

जंक की तलाश करते समय, सर्फेसफ्लिंगर के तहत फ्रेममिस्ड पंक्ति की जांच करें। FrameMissed HWC2 द्वारा प्रदान किया गया जीवन की गुणवत्ता में सुधार है। अन्य उपकरणों के लिए सिस्ट्रेस देखते समय, यदि डिवाइस HWC2 का उपयोग नहीं करता है, तो फ़्रेम मिस्ड पंक्ति मौजूद नहीं हो सकती है। किसी भी मामले में, FrameMissed को SurfaceFlinger के साथ सहसंबद्ध किया गया है, जिसमें इसके अत्यंत नियमित रनटाइम में से एक गायब है और ऐप के लिए एक अपरिवर्तित लंबित-बफर गणना ( com.prefabulated.touchlatency ) एक बनाम।

सरफेसफ्लिंगर के साथ फ्रेम मिस्ड सहसंबंध
चित्र 11. सरफेसफ्लिंगर के साथ फ्रेम मिस्ड सहसंबंध

चित्र 11 15598.29&nbps;ms पर एक चूके हुए फ्रेम को दिखाता है। सरफेसफ्लिंगर बनाम सिंक अंतराल पर कुछ समय के लिए जाग गया और बिना कोई काम किए वापस सो गया, जिसका अर्थ है कि सर्फेसफ्लिंगर ने निर्धारित किया कि यह फिर से डिस्प्ले पर एक फ्रेम भेजने की कोशिश करने लायक नहीं था। क्यों?

यह समझने के लिए कि इस फ्रेम के लिए पाइपलाइन कैसे टूट गई, पहले ऊपर दिए गए वर्किंग फ्रेम उदाहरण की समीक्षा करके देखें कि सिस्ट्रेस में एक सामान्य UI पाइपलाइन कैसे दिखाई देती है। तैयार होने पर, छूटे हुए फ्रेम पर वापस आएं और पीछे की ओर काम करें। ध्यान दें कि सर्फेसफ्लिंगर जागता है और तुरंत सो जाता है। TouchLatency से लंबित फ़्रेमों की संख्या देखते समय, दो फ़्रेम होते हैं (क्या हो रहा है यह पता लगाने में मदद करने के लिए एक अच्छा सुराग)।

सरफेसफ्लिंगर जागता है और तुरंत सो जाता है
चित्र 12. सरफेसफ्लिंगर जागता है और तुरंत सो जाता है

क्योंकि हमारे पास SurfaceFlinger में फ़्रेम हैं, यह कोई ऐप समस्या नहीं है। इसके अलावा, SurfaceFlinger सही समय पर जाग रहा है, इसलिए यह कोई SurfaceFlinger समस्या नहीं है। यदि सरफेसफ्लिंगर और ऐप दोनों सामान्य दिखते हैं, तो यह शायद ड्राइवर की समस्या है।

क्योंकि mdss और sync ट्रेसप्वाइंट सक्षम हैं, हम फ़ेंस (डिस्प्ले ड्राइवर और सर्फेसफ़्लिंगर के बीच साझा) के बारे में जानकारी प्राप्त कर सकते हैं जो डिस्प्ले पर फ़्रेम सबमिट किए जाने पर नियंत्रित करते हैं। ये बाड़ mdss_fb0_retire के तहत सूचीबद्ध हैं, जो दर्शाता है कि प्रदर्शन पर एक फ्रेम कब है। ये बाड़ sync ट्रेस श्रेणी के हिस्से के रूप में प्रदान की जाती हैं। सर्फेसफ्लिंगर में विशेष घटनाओं के अनुरूप कौन सी बाड़ आपके एसओसी और ड्राइवर स्टैक पर निर्भर करती है, इसलिए अपने निशान में बाड़ श्रेणियों के अर्थ को समझने के लिए अपने एसओसी विक्रेता के साथ काम करें।

mdss_fb0_सेवानिवृत्त बाड़
चित्र 13. mdss_fb0_सेवानिवृत्त बाड़

चित्र 13 एक ऐसा फ़्रेम दिखाता है जो अपेक्षित रूप से 16.7 ms के बजाय 33 ms के लिए प्रदर्शित किया गया था। उस टुकड़े के आधे रास्ते में, उस फ्रेम को एक नए से बदल दिया जाना चाहिए था, लेकिन नहीं था। पिछला फ्रेम देखें और कुछ भी देखें।

बस्टेड फ्रेम से पहले का फ्रेम
चित्रा 14. बस्टेड फ्रेम के पिछले फ्रेम

चित्र 14 में 14.482 एमएस फ्रेम दिखाया गया है। टूटा हुआ दो-फ्रेम खंड 33.6 एमएस था, जो मोटे तौर पर हम दो फ्रेम के लिए उम्मीद करेंगे (हम 60 हर्ट्ज पर प्रस्तुत करते हैं, 16.7 एमएस प्रति फ्रेम, जो करीब है)। लेकिन 14.482 एमएस 16.7 एमएस के करीब नहीं है, यह दर्शाता है कि डिस्प्ले पाइप में कुछ गड़बड़ है।

जाँच करें कि यह बाड़ कहाँ समाप्त होती है यह निर्धारित करने के लिए कि यह क्या नियंत्रित करता है।

बाड़ के अंत की जांच करें
चित्रा 15. बाड़ के अंत की जांच करें

एक वर्कक्यू में __vsync_retire_work_handler होता है, जो बाड़ बदलने पर चल रहा होता है। कर्नेल स्रोत को देखते हुए, आप देख सकते हैं कि यह डिस्प्ले ड्राइवर का हिस्सा है। यह प्रदर्शन पाइपलाइन के लिए महत्वपूर्ण पथ पर प्रतीत होता है, इसलिए इसे जितनी जल्दी हो सके चलाना चाहिए। यह 70 या तो के लिए चलने योग्य है (लंबे समय तक शेड्यूलिंग विलंब नहीं), लेकिन यह एक वर्कक्यू है और सटीक रूप से शेड्यूल नहीं किया जा सकता है।

यह निर्धारित करने के लिए पिछले फ्रेम की जाँच करें कि क्या उसने योगदान दिया है; कभी-कभी घबराहट समय के साथ जुड़ सकती है और अंततः एक चूक की समय सीमा का कारण बन सकती है।

पिछला फ्रेम
चित्रा 16. पिछला फ्रेम

kworker पर चलने योग्य रेखा दिखाई नहीं देती है क्योंकि दर्शक इसे चयनित होने पर सफेद कर देता है, लेकिन आंकड़े कहानी बताते हैं: डिस्प्ले पाइपलाइन के महत्वपूर्ण पथ के लिए 2.3 ms शेड्यूलर विलंब खराब है। जारी रखने से पहले, उस विलंब को ठीक करें जो डिस्प्ले पाइपलाइन के महत्वपूर्ण पथ को एक वर्कक्यू (जो SCHED_OTHER CFS थ्रेड के रूप में चलता है) से एक समर्पित SCHED_FIFO kthread पर ले जाकर ठीक करता है। इस फ़ंक्शन को समय की गारंटी की आवश्यकता होती है जो वर्कक्यू प्रदान नहीं कर सकता (और इसका इरादा नहीं है)।

क्या यही वजह है जाम की? निर्णायक रूप से कहना मुश्किल है। आसानी से निदान होने वाले मामलों जैसे कि कर्नेल लॉक विवाद के कारण डिस्प्ले-क्रिटिकल थ्रेड्स सो जाते हैं, निशान आमतौर पर समस्या को निर्दिष्ट नहीं करते हैं। क्या यह घबराना फ्रेम गिराए जाने का कारण हो सकता है? बिल्कुल। बाड़ का समय 16.7 एमएस होना चाहिए, लेकिन वे उस फ्रेम के बिल्कुल भी करीब नहीं हैं जो गिराए गए फ्रेम तक जाता है। यह देखते हुए कि डिस्प्ले पाइपलाइन कितनी कसकर युग्मित है, यह संभव है कि बाड़ के समय के आसपास घबराहट के परिणामस्वरूप एक गिरा हुआ फ्रेम हो।

इस उदाहरण में, समाधान में __vsync_retire_work_handler को __vsync_retire_work_handler से एक समर्पित kthread में कनवर्ट करना शामिल है। इसके परिणामस्वरूप बाउंसिंग बॉल टेस्ट में ध्यान देने योग्य घबराहट में सुधार हुआ और जंक कम हो गया। बाद के निशान बाड़ समय दिखाते हैं जो 16.7 एमएस के बहुत करीब होवर करते हैं।