एंड्रॉइड डिवाइस के प्रदर्शन का विश्लेषण करने के लिए सिस्ट्रेस प्राथमिक उपकरण है। हालाँकि, यह वास्तव में अन्य उपकरणों के चारों ओर एक आवरण है। यह atrace के चारों ओर होस्ट-साइड रैपर है, डिवाइस-साइड निष्पादन योग्य है जो यूजरस्पेस ट्रेसिंग को नियंत्रित करता है और ftrace सेट करता है, और लिनक्स कर्नेल में प्राथमिक ट्रेसिंग तंत्र है। सिस्ट्रेस ट्रेसिंग को सक्षम करने के लिए एट्रेस का उपयोग करता है, फिर फ़ट्रेस बफर को पढ़ता है और इसे एक स्व-निहित HTML व्यूअर में लपेटता है। (हालांकि नए कर्नेल में लिनक्स एन्हांस्ड बर्कले पैकेट फ़िल्टर (eBPF) के लिए समर्थन है, निम्नलिखित दस्तावेज़ 3.18 कर्नेल (कोई eFPF नहीं) से संबंधित है क्योंकि पिक्सेल/पिक्सेल XL पर इसका उपयोग किया गया था।)
सिस्ट्रेस का स्वामित्व Google Android और Google Chrome टीमों के पास है और यह कैटापुल्ट प्रोजेक्ट के हिस्से के रूप में खुला स्रोत है। सिस्ट्रेस के अलावा, कैटापुल्ट में अन्य उपयोगी उपयोगिताएँ भी शामिल हैं। उदाहरण के लिए, एफट्रेस में सिस्ट्रेस या एट्रेस द्वारा सीधे सक्षम की जा सकने वाली सुविधाओं से अधिक सुविधाएं हैं और इसमें कुछ उन्नत कार्यक्षमताएं हैं जो प्रदर्शन समस्याओं को डीबग करने के लिए महत्वपूर्ण हैं। (इन सुविधाओं के लिए रूट एक्सेस और अक्सर एक नए कर्नेल की आवश्यकता होती है।)
चल रहा सिस्ट्रेस
Pixel/Pixel XL पर जिटर डीबग करते समय, निम्न कमांड से प्रारंभ करें:
./systrace.py sched freq idle am wm gfx view sync binder_driver irq workq input -b 96000
जब GPU और डिस्प्ले पाइपलाइन गतिविधि के लिए आवश्यक अतिरिक्त ट्रेसप्वाइंट के साथ जोड़ा जाता है, तो यह आपको उपयोगकर्ता इनपुट से स्क्रीन पर प्रदर्शित फ्रेम तक ट्रेस करने की क्षमता देता है। इवेंट खोने से बचने के लिए बफ़र आकार को कुछ बड़े पर सेट करें (क्योंकि बड़े बफ़र के बिना कुछ सीपीयू में ट्रेस में कुछ बिंदु के बाद कोई इवेंट नहीं होता है)।
सिस्ट्रेस से गुजरते समय, ध्यान रखें कि प्रत्येक घटना सीपीयू पर किसी चीज से ट्रिगर होती है ।
क्योंकि सिस्ट्रेस फ़ट्रेस के शीर्ष पर बनाया गया है और फ़ट्रेस सीपीयू पर चलता है, सीपीयू पर कुछ फ़ट्रेस बफ़र लिखना होगा जो हार्डवेयर परिवर्तनों को लॉग करता है। इसका मतलब यह है कि यदि आप इस बारे में उत्सुक हैं कि डिस्प्ले बाड़ की स्थिति क्यों बदली है, तो आप देख सकते हैं कि इसके संक्रमण के सटीक बिंदु पर सीपीयू पर क्या चल रहा था (सीपीयू पर चलने वाली किसी चीज ने लॉग में उस बदलाव को ट्रिगर किया)। यह अवधारणा सिस्ट्रेस का उपयोग करके प्रदर्शन का विश्लेषण करने का आधार है।
उदाहरण: कार्यशील ढाँचा
यह उदाहरण सामान्य यूआई पाइपलाइन के लिए सिस्ट्रेस का वर्णन करता है। उदाहरण के साथ अनुसरण करने के लिए, ट्रेस की ज़िप फ़ाइल डाउनलोड करें (जिसमें इस अनुभाग में संदर्भित अन्य ट्रेस भी शामिल हैं), फ़ाइल को अनज़िप करें, और अपने ब्राउज़र में systrace_tutorial.html
फ़ाइल खोलें। सावधान रहें कि यह सिस्ट्रेस एक बड़ी फ़ाइल है; जब तक आप अपने दिन-प्रतिदिन के काम में सिस्ट्रेस का उपयोग नहीं करते हैं, यह संभवतः बहुत अधिक जानकारी वाला एक बहुत बड़ा ट्रेस है, जितना आपने पहले कभी किसी एक ट्रेस में देखा है।
टचलेटेंसी जैसे सुसंगत, आवधिक कार्यभार के लिए, यूआई पाइपलाइन में निम्नलिखित शामिल हैं:
- सरफेसफ्लिंगर में इवेंट थ्रेड ऐप यूआई थ्रेड को जगाता है, यह संकेत देता है कि यह एक नया फ्रेम प्रस्तुत करने का समय है।
- ऐप सीपीयू और जीपीयू संसाधनों का उपयोग करके यूआई थ्रेड, रेंडरथ्रेड और एचडब्ल्यूयूआईटास्क में एक फ्रेम प्रस्तुत करता है। यह यूआई के लिए खर्च की गई क्षमता का बड़ा हिस्सा है।
- ऐप एक बाइंडर का उपयोग करके रेंडर किए गए फ्रेम को सरफेसफ्लिंगर को भेजता है, फिर सरफेसफ्लिंगर सो जाता है।
- सरफेसफ्लिंगर में दूसरा इवेंटथ्रेड, कंपोजिशन को ट्रिगर करने और आउटपुट प्रदर्शित करने के लिए सरफेसफ्लिंगर को जगाता है। यदि सरफेसफ्लिंगर यह निर्धारित करता है कि करने के लिए कोई काम नहीं है, तो वह वापस सो जाता है।
- सरफेसफ्लिंगर हार्डवेयर कंपोजर (एचडब्ल्यूसी)/हार्डवेयर कंपोजर 2 (एचडब्ल्यूसी2) या जीएल का उपयोग करके संरचना को संभालता है। HWC/HWC2 संरचना तेज़ और कम शक्ति वाली है लेकिन चिप पर सिस्टम (SoC) के आधार पर इसकी सीमाएँ हैं। इसमें आमतौर पर ~4-6 एमएस लगते हैं, लेकिन चरण 2 के साथ ओवरलैप हो सकता है क्योंकि एंड्रॉइड ऐप्स हमेशा ट्रिपल बफर्ड होते हैं। (हालांकि ऐप्स हमेशा ट्रिपल बफ़र किए जाते हैं, सरफेसफ्लिंगर में केवल एक लंबित फ़्रेम प्रतीक्षा कर सकता है, जो इसे डबल बफ़रिंग के समान प्रतीत होता है।)
- सरफेसफ्लिंगर विक्रेता ड्राइवर के साथ प्रदर्शित करने के लिए अंतिम आउटपुट भेजता है और इवेंटथ्रेड वेकअप की प्रतीक्षा करते हुए वापस सो जाता है।
आइए 15409 एमएस से शुरू होने वाले फ्रेम पर चलें:
चित्र 1 सामान्य फ्रेम से घिरा एक सामान्य फ्रेम है, इसलिए यह समझने के लिए एक अच्छा प्रारंभिक बिंदु है कि यूआई पाइपलाइन कैसे काम करती है। TouchLatency के लिए UI थ्रेड पंक्ति में अलग-अलग समय पर अलग-अलग रंग शामिल हैं। बार्स धागे के लिए अलग-अलग अवस्थाओं को दर्शाते हैं:
- स्लेटी । सोना।
- नीला। चलाने योग्य (यह चल सकता है, लेकिन शेड्यूलर ने इसे चलाने के लिए अभी तक नहीं चुना है)।
- हरा। सक्रिय रूप से चल रहा है (अनुसूचक सोचता है कि यह चल रहा है)।
- लाल। निर्बाध नींद (आम तौर पर कर्नेल में ताला लगाकर सोना)। I/O लोड का सूचक हो सकता है. प्रदर्शन समस्याओं को डीबग करने के लिए अत्यंत उपयोगी।
- नारंगी। I/O लोड के कारण निर्बाध नींद।
निर्बाध नींद का कारण देखने के लिए ( sched_blocked_reason
ट्रेसप्वाइंट से उपलब्ध), लाल निर्बाध नींद स्लाइस का चयन करें।
जब इवेंटथ्रेड चल रहा होता है, तो TouchLatency के लिए UI थ्रेड चलने योग्य हो जाता है। यह देखने के लिए कि इसे किसने जगाया, नीले अनुभाग पर क्लिक करें।
चित्र 2 से पता चलता है कि TouchLatency UI थ्रेड को tid 6843 द्वारा जगाया गया था, जो इवेंट थ्रेड से मेल खाता है। यूआई थ्रेड जागता है, एक फ्रेम प्रस्तुत करता है, और सर्फेसफ्लिंगर के उपभोग के लिए इसे एनक्यू करता है।
यदि binder_driver
टैग किसी ट्रेस में सक्षम है, तो आप उस लेनदेन में शामिल सभी प्रक्रियाओं की जानकारी देखने के लिए एक बाइंडर लेनदेन का चयन कर सकते हैं।
चित्र 4 से पता चलता है कि, 15,423.65 एमएस पर सरफेसफ्लिंगर में बाइंडर:6832_1 टीआईडी 9579 के कारण चलने योग्य हो जाता है, जो कि टचलेटेंसी का रेंडरथ्रेड है। आप बाइंडर लेनदेन के दोनों ओर क्यूबफ़र भी देख सकते हैं।
SurfaceFlinger पक्ष पर क्यूबफ़र के दौरान, TouchLatency से लंबित फ़्रेमों की संख्या 1 से 2 हो जाती है।
चित्र 5 ट्रिपल बफ़रिंग दिखाता है, जहां दो पूर्ण फ़्रेम हैं और ऐप तीसरा रेंडर करना शुरू करने वाला है। ऐसा इसलिए है क्योंकि हमने पहले ही कुछ फ़्रेम हटा दिए हैं, इसलिए ऐप आगे गिराए गए फ़्रेमों से बचने के लिए एक के बजाय दो लंबित फ़्रेम रखता है।
इसके तुरंत बाद, सरफेसफ्लिंगर का मुख्य थ्रेड दूसरे इवेंट थ्रेड द्वारा जागृत हो जाता है ताकि यह पुराने लंबित फ्रेम को डिस्प्ले पर आउटपुट कर सके:
सरफेसफ्लिंगर सबसे पहले पुराने लंबित बफ़र को लैच करता है, जिसके कारण लंबित बफ़र की संख्या 2 से घटकर 1 हो जाती है।
बफ़र को लैच करने के बाद, SurfaceFlinger कंपोज़िशन सेट करता है और अंतिम फ़्रेम को डिस्प्ले पर सबमिट करता है। (इनमें से कुछ अनुभाग mdss
ट्रेसप्वाइंट के भाग के रूप में सक्षम हैं, इसलिए हो सकता है कि वे आपके SoC पर शामिल न हों।)
इसके बाद, mdss_fb0
CPU 0 पर सक्रिय होता है। mdss_fb0
डिस्प्ले पर रेंडर किए गए फ्रेम को आउटपुट करने के लिए डिस्प्ले पाइपलाइन का कर्नेल थ्रेड है। हम ट्रेस में mdss_fb0
उसकी अपनी पंक्ति के रूप में देख सकते हैं (देखने के लिए नीचे स्क्रॉल करें)।
mdss_fb0
जागता है, थोड़ी देर दौड़ता है, निर्बाध नींद में प्रवेश करता है, फिर जागता है।
उदाहरण: गैर-कार्यशील फ़्रेम
यह उदाहरण पिक्सेल/पिक्सेल एक्सएल जिटर को डीबग करने के लिए उपयोग किए जाने वाले सिस्ट्रेस का वर्णन करता है। उदाहरण के साथ अनुसरण करने के लिए, ट्रेस की ज़िप फ़ाइल डाउनलोड करें (जिसमें इस अनुभाग में संदर्भित अन्य ट्रेस शामिल हैं), फ़ाइल को अनज़िप करें, और अपने ब्राउज़र में systrace_tutorial.html
फ़ाइल खोलें।
जब आप सिस्ट्रेस खोलेंगे, तो आपको कुछ इस तरह दिखाई देगा:
जंक की तलाश करते समय, SurfaceFlinger के अंतर्गत फ़्रेममिस्ड पंक्ति की जाँच करें। फ़्रेममिस्ड HWC2 द्वारा प्रदान किया गया जीवन की गुणवत्ता में सुधार है। अन्य डिवाइसों के लिए सिस्ट्रेस देखते समय, यदि डिवाइस HWC2 का उपयोग नहीं करता है, तो फ़्रेममिस्ड पंक्ति मौजूद नहीं हो सकती है। किसी भी मामले में, फ्रेममिस्ड का संबंध सरफेसफ्लिंगर से है, जो इसके बेहद नियमित रनटाइम में से एक को गायब कर देता है और ऐप के लिए एक अपरिवर्तित लंबित-बफर गिनती ( com.prefabulated.touchlatency
) एक vsync पर है।
चित्र 11 15598.29&nbps;ms पर एक छूटा हुआ फ्रेम दिखाता है। सरफेसफ्लिंगर vsync अंतराल पर थोड़ी देर के लिए उठा और बिना कोई काम किए वापस सो गया, जिसका मतलब है कि सर्फेसफ्लिंगर ने निर्धारित किया कि डिस्प्ले पर फिर से फ्रेम भेजने की कोशिश करना उचित नहीं है। क्यों?
यह समझने के लिए कि इस फ्रेम के लिए पाइपलाइन कैसे टूट गई, पहले ऊपर दिए गए कार्यशील फ्रेम उदाहरण की समीक्षा करें और देखें कि सिस्ट्रेस में एक सामान्य यूआई पाइपलाइन कैसे दिखाई देती है। तैयार होने पर, छूटे हुए फ्रेम पर वापस लौटें और पीछे की ओर काम करें। ध्यान दें कि सरफेसफ्लिंगर जागता है और तुरंत सो जाता है। TouchLatency से लंबित फ़्रेमों की संख्या देखते समय, दो फ़्रेम होते हैं (क्या हो रहा है यह पता लगाने में मदद करने के लिए एक अच्छा संकेत)।
चूँकि हमारे पास SurfaceFlinger में फ़्रेम हैं, इसलिए यह कोई ऐप समस्या नहीं है। इसके अलावा, SurfaceFlinger सही समय पर जाग रहा है, इसलिए यह SurfaceFlinger समस्या नहीं है। यदि SurfaceFlinger और ऐप दोनों सामान्य दिखते हैं, तो संभवतः यह ड्राइवर समस्या है।
क्योंकि mdss
और sync
ट्रेसप्वाइंट सक्षम हैं, हम बाड़ (डिस्प्ले ड्राइवर और सरफेसफ्लिंगर के बीच साझा) के बारे में जानकारी प्राप्त कर सकते हैं जो डिस्प्ले पर फ्रेम सबमिट होने पर नियंत्रण करते हैं। ये बाड़ें mdss_fb0_retire
के अंतर्गत सूचीबद्ध हैं, जो दर्शाता है कि कोई फ़्रेम डिस्प्ले पर कब है। ये बाड़ें sync
ट्रेस श्रेणी के हिस्से के रूप में प्रदान की गई हैं। सरफेसफ्लिंगर में विशेष घटनाओं के अनुरूप कौन सी बाड़ आपके एसओसी और ड्राइवर स्टैक पर निर्भर करती है, इसलिए अपने ट्रेस में बाड़ श्रेणियों के अर्थ को समझने के लिए अपने एसओसी विक्रेता के साथ काम करें।
चित्र 13 एक फ्रेम दिखाता है जो 33 एमएस के लिए प्रदर्शित किया गया था, न कि 16.7 एमएस के लिए जैसा कि अपेक्षित था। उस टुकड़े के आधे रास्ते में, उस फ्रेम को एक नए से बदल दिया जाना चाहिए था, लेकिन ऐसा नहीं किया गया। पिछला फ़्रेम देखें और कुछ भी ढूंढें।
चित्र 14 एक फ्रेम 14.482 एमएस दिखाता है। टूटा हुआ दो-फ़्रेम खंड 33.6 एमएस था, जो मोटे तौर पर हम दो फ़्रेमों के लिए अपेक्षा करते हैं (हम 60 हर्ट्ज़, 16.7 एमएस प्रति फ्रेम पर प्रस्तुत करते हैं, जो करीब है)। लेकिन 14.482 एमएस बिल्कुल भी 16.7 एमएस के करीब नहीं है, जिससे पता चलता है कि डिस्प्ले पाइप में कुछ बहुत गड़बड़ है।
यह निर्धारित करने के लिए कि उसे कौन नियंत्रित करता है, ठीक-ठीक जाँच करें कि वह बाड़ कहाँ समाप्त होती है।
वर्कक्यू में __vsync_retire_work_handler
होता है, जो बाड़ बदलने पर चलता है। कर्नेल स्रोत को देखने पर, आप देख सकते हैं कि यह डिस्प्ले ड्राइवर का हिस्सा है। ऐसा प्रतीत होता है कि यह डिस्प्ले पाइपलाइन के लिए महत्वपूर्ण पथ पर है, इसलिए इसे जितनी जल्दी हो सके चलना चाहिए। यह लगभग 70 लोगों के लिए चलाने योग्य है (शेड्यूलिंग में कोई लंबी देरी नहीं), लेकिन यह एक कार्य कतार है और हो सकता है कि इसे सटीक रूप से शेड्यूल न किया जाए।
यह निर्धारित करने के लिए कि क्या उसने योगदान दिया है, पिछले फ़्रेम की जाँच करें; कभी-कभी घबराहट समय के साथ बढ़ती जा सकती है और अंततः समय सीमा चूकने का कारण बन सकती है।
Kworker पर चलने योग्य लाइन दिखाई नहीं देती है क्योंकि दर्शक इसे चयनित होने पर सफेद कर देता है, लेकिन आंकड़े कहानी बताते हैं: डिस्प्ले पाइपलाइन क्रिटिकल पथ के हिस्से के लिए 2.3 एमएस शेड्यूलर विलंब खराब है। जारी रखने से पहले, डिस्प्ले पाइपलाइन क्रिटिकल पथ के इस हिस्से को वर्कक्यू (जो SCHED_OTHER
CFS थ्रेड के रूप में चलता है) से एक समर्पित SCHED_FIFO
kthread पर ले जाकर देरी को ठीक करें। इस फ़ंक्शन को समय की गारंटी की आवश्यकता होती है जो कार्य कतारें प्रदान नहीं कर सकती (और करने का इरादा नहीं है)।
क्या ये है जंक की वजह? निर्णायक रूप से कहना कठिन है। निदान में आसान मामलों जैसे कि कर्नेल लॉक विवाद के कारण डिस्प्ले-क्रिटिकल थ्रेड्स निष्क्रिय हो जाते हैं, निशान आमतौर पर समस्या को निर्दिष्ट नहीं करते हैं। क्या यह घबराहट फ्रेम गिरने का कारण हो सकती है? बिल्कुल। बाड़ का समय 16.7 एमएस होना चाहिए, लेकिन गिराए गए फ्रेम तक जाने वाले फ्रेम में वे बिल्कुल भी इसके करीब नहीं हैं। यह देखते हुए कि डिस्प्ले पाइपलाइन कितनी मजबूती से जुड़ी हुई है, यह संभव है कि बाड़ के समय के आसपास घबराहट के कारण फ्रेम गिर गया।
इस उदाहरण में, समाधान में __vsync_retire_work_handler
वर्कक्यू से समर्पित kthread में परिवर्तित करना शामिल है। इसके परिणामस्वरूप घबराहट में उल्लेखनीय सुधार हुआ और बाउंसिंग बॉल टेस्ट में जंक कम हो गया। बाद के निशान बाड़ के समय को दर्शाते हैं जो 16.7 एमएस के बहुत करीब मंडराता है।