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

चित्र 1 सामान्य फ्रेम से घिरा एक सामान्य फ्रेम है, इसलिए यह समझने के लिए एक अच्छा प्रारंभिक बिंदु है कि UI पाइपलाइन कैसे काम करती है। TouchLatency के लिए UI थ्रेड पंक्ति में अलग-अलग समय पर अलग-अलग रंग शामिल हैं। बार्स धागे के लिए अलग-अलग राज्यों को दर्शाते हैं:
- ग्रे । सोना।
- नीला। रननेबल (यह चल सकता है, लेकिन शेड्यूलर ने इसे अभी तक चलाने के लिए नहीं चुना है)।
- हरा। सक्रिय रूप से चल रहा है (अनुसूचक सोचता है कि यह चल रहा है)।
- लाल। निर्बाध नींद (आमतौर पर कर्नेल में लॉक पर सोना)। I/O लोड का संकेत हो सकता है। प्रदर्शन समस्याओं को डीबग करने के लिए अत्यंत उपयोगी।
- संतरा। I/O लोड के कारण निर्बाध नींद।
निर्बाध नींद का कारण देखने के लिए ( sched_blocked_reason
ट्रेसपॉइंट से उपलब्ध), लाल निर्बाध स्लीप स्लाइस का चयन करें।
जबकि EventThread चल रहा है, TouchLatency के लिए UI थ्रेड चलाने योग्य हो जाता है। यह देखने के लिए कि इसने क्या जगाया, नीले अनुभाग पर क्लिक करें।

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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