प्रोफ़ाइल जीपीयू रेंडरिंग के ज़रिए विश्लेषण करें

प्रोफ़ाइल जीपीयू रेंडरिंग टूल से पता चलता है कि रेंडरिंग की प्रोसेस के हर चरण में, पिछले फ़्रेम को रेंडर होने में कितना समय लगता है. इस जानकारी से, आपको पाइपलाइन में रुकावटों की पहचान करने में मदद मिल सकती है. इससे, आपको यह पता चल सकता है कि अपने ऐप्लिकेशन की रेंडरिंग परफ़ॉर्मेंस को बेहतर बनाने के लिए, किन चीज़ों को ऑप्टिमाइज़ करना है.

इस पेज पर, पाइपलाइन के हर चरण के दौरान होने वाली प्रोसेस के बारे में कम शब्दों में बताया गया है. साथ ही, उन समस्याओं के बारे में भी बताया गया है जिनकी वजह से प्रोसेस में रुकावट आ सकती है. इस पेज को पढ़ने से पहले, आपको प्रोफ़ाइल जीपीयू रेंडरिंग में दी गई जानकारी के बारे में पता होना चाहिए. इसके अलावा, सभी स्टेज एक-दूसरे में कैसे फ़िट होते हैं, यह समझने के लिए रेंडरिंग पाइपलाइन के काम करने का तरीका जानना मददगार हो सकता है.

विज़ुअल के तौर पर दिखाना

प्रोफ़ाइल जीपीयू रेंडरिंग टूल, स्टेज और उनसे जुड़े समय को ग्राफ़ के तौर पर दिखाता है: कलर कोड वाला हिस्टोग्राम. पहली इमेज में, ऐसे डिसप्ले का उदाहरण दिखाया गया है.

पहली इमेज. प्रोफ़ाइल जीपीयू रेंडरिंग ग्राफ़

प्रोफ़ाइल GPU रेंडरिंग ग्राफ़ में दिखाए गए हर वर्टिकल बार का हर सेगमेंट, पाइपलाइन के किसी चरण को दिखाता है. साथ ही, बार ग्राफ़ में किसी खास रंग का इस्तेमाल करके उसे हाइलाइट किया जाता है. दूसरे चित्र में, दिखाए गए हर रंग का मतलब बताया गया है.

दूसरी इमेज. प्रोफ़ाइल जीपीयू रेंडरिंग ग्राफ़ लेजेंड

हर रंग का मतलब समझने के बाद, अपने ऐप्लिकेशन के कुछ खास हिस्सों को टारगेट किया जा सकता है, ताकि रेंडरिंग की परफ़ॉर्मेंस को ऑप्टिमाइज़ किया जा सके.

स्टेज और उनके मतलब

इस सेक्शन में बताया गया है कि दूसरे चरण में हर रंग के हिसाब से, किस चरण में क्या होता है. साथ ही, इसमें यह भी बताया गया है कि रुकावट की वजहें क्या हो सकती हैं.

इनपुट मैनेज करना

पाइपलाइन के इनपुट हैंडलिंग स्टेज से पता चलता है कि ऐप्लिकेशन ने इनपुट इवेंट को कितने समय तक हैंडल किया है. इस मेट्रिक से पता चलता है कि इनपुट इवेंट कॉलबैक की वजह से, ऐप्लिकेशन को कोड को लागू करने में कितना समय लगा.

जब यह सेगमेंट बड़ा हो

आम तौर पर, इस सेक्शन में ज़्यादा वैल्यू होने का मतलब है कि इनपुट-हैंडलर इवेंट कॉलबैक में बहुत ज़्यादा या बहुत मुश्किल काम हो रहा है. ये कॉलबैक हमेशा मुख्य थ्रेड पर होते हैं. इसलिए, इस समस्या को हल करने का मकसद, काम को सीधे तौर पर ऑप्टिमाइज़ करना या काम को किसी अलग थ्रेड पर लोड करना होता है.

यह भी ध्यान देने वाली बात है कि RecyclerView इस चरण में स्क्रोलिंग दिख सकती है. RecyclerView टच इवेंट का इस्तेमाल करते ही, स्क्रोल करता है. इस वजह से, आइटम के नए व्यू की संख्या बढ़ सकती है या अपने-आप भर सकती है. इस वजह से, इस कार्रवाई को जल्द से जल्द पूरा करना ज़रूरी है. Traceview याSystrace जैसे प्रोफ़ाइलिंग टूल आगे की जांच में आपकी सहायता कर सकते हैं.

ऐनिमेशन

ऐनिमेशन फ़ेज़ से पता चलता है कि उस फ़्रेम में चल रहे सभी ऐनिमेटर्स का आकलन करने में कितना समय लगा. आम तौर पर, ऐनिमेशन बनाने वाले ये लोग ObjectAnimator, ViewPropertyAnimator, और ट्रांज़िशन का इस्तेमाल करते हैं.

जब यह सेगमेंट बड़ा हो

इस क्षेत्र में ज़्यादा वैल्यू, आम तौर पर उस काम का नतीजा होती है जिसे ऐनिमेशन में कुछ बदलाव की वजह से लागू किया जाता है. उदाहरण के लिए, आपके ListView या RecyclerView को स्क्रोल करने वाले फ़्लिंग ऐनिमेशन की वजह से, वीडियो देखने वालों की संख्या काफ़ी बढ़ जाती है और जनसंख्या ज़्यादा हो जाती है.

मेज़रमेंट/लेआउट

Android, स्क्रीन पर आपके व्यू आइटम दिखाने के लिए, आपकी व्यू हैरारकी में मौजूद लेआउट और व्यू पर दो खास कार्रवाइयां करता है.

सबसे पहले, सिस्टम व्यू आइटम को मेज़र करता है. हर व्यू और लेआउट में, स्क्रीन पर ऑब्जेक्ट के साइज़ के बारे में बताने वाला खास डेटा होता है. कुछ व्यू का साइज़ तय हो सकता है. वहीं, कुछ व्यू का साइज़ पैरंट लेआउट कंटेनर के साइज़ के हिसाब से बदल सकता है

दूसरा, सिस्टम व्यू आइटम लेआउट करता है. सिस्टम, बच्चों के व्यू के साइज़ का हिसाब लगाने के बाद, स्क्रीन पर व्यू का लेआउट तय कर सकता है. साथ ही, व्यू का साइज़ और पोज़िशन तय कर सकता है.

यह सिस्टम, सिर्फ़ खींचे जाने वाले व्यू के लिए ही नहीं, बल्कि उन व्यू की पैरंट हैरारकी के लिए भी मेज़रमेंट और लेआउट करता है. यह प्रोसेस, रूट व्यू तक की जाती है.

जब यह सेगमेंट बड़ा हो

अगर आपका ऐप्लिकेशन इस इलाके में एक फ़्रेम के अंदर काफ़ी ज़्यादा समय बिताता है, तो आम तौर पर इसकी वजह यह हो सकती है कि ज़्यादा व्यू मिलने की ज़रूरत है. इसके अलावा, इसकी वजह भी हो सकती है कि आपके हैरारकी में मौजूद गलत जगह पर दोगुने टैक्स देने से जुड़ी समस्याएं हों. इनमें से किसी भी मामले में, परफ़ॉर्मेंस पर ध्यान देने के लिए व्यू हैरारकी (व्यू और व्यू ग्रुप के लेआउट का क्रम) की परफ़ॉर्मेंस को बेहतर करना ज़रूरी होता है.

onLayout(boolean, int, int, int, int) या onMeasure(int, int) में जोड़े गए कोड की वजह से, परफ़ॉर्मेंस से जुड़ी समस्याएं भी आ सकती हैं. Traceview और Systrace की मदद से, कॉलस्टैक की जांच की जा सकती है और कोड की समस्याओं का पता लगाया जा सकता है.

जगह बदलना

ड्रॉ स्टेज, व्यू के रेंडरिंग ऑपरेशन को नेटिव ड्रॉइंग कमांड के क्रम में बदल देता है. जैसे, बैकग्राउंड बनाना या टेक्स्ट ड्रॉइंग करना. सिस्टम इन निर्देशों को एक डिसप्ले सूची में कैप्चर करता है.

'ड्रॉ करें' बार यह रिकॉर्ड करता है कि स्क्रीन पर इस फ़्रेम को अपडेट करने वाले सभी व्यू को डिसप्ले सूची में कमांड कैप्चर करने में कितना समय लगता है. मापा गया समय, ऐसे किसी भी कोड पर लागू होता है जिसे आपने अपने ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) ऑब्जेक्ट में जोड़ा है. इस तरह के कोड के उदाहरणों में, onDraw(), dispatchDraw(), और Drawable क्लास की सब-क्लास से जुड़े कई draw ()methods शामिल हो सकते हैं.

जब यह सेगमेंट बड़ा हो

आसान शब्दों में कहें, तो इस मेट्रिक से यह पता चलता है कि अमान्य हर व्यू के लिए, onDraw() को सभी कॉल चलाने में कितना समय लगा. इस मेज़रमेंट में, बच्चों को ड्रॉ करने के निर्देश देने और ऐप्लिकेशन में मौजूद ड्रॉ करने की सुविधाओं का इस्तेमाल करने में लगने वाला समय शामिल होता है. इस वजह से, जब आपको बार में यह बढ़ोतरी दिखती है, तो हो सकता है कि कुछ व्यू अचानक अमान्य हो गए हों. अमान्य होने पर, व्यू की डिसप्ले सूचियों को फिर से जनरेट करना ज़रूरी हो जाता है. इसके अलावा, कुछ कस्टम व्यू के onDraw() तरीकों में बहुत जटिल लॉजिक होने की वजह से भी, प्रोसेस में ज़्यादा समय लग सकता है.

सिंक करें/अपलोड करें

सिंक और अपलोड मेट्रिक से उस समय के बारे में पता चलता है जो मौजूदा फ़्रेम के दौरान, सीपीयू मेमोरी से जीपीयू मेमोरी में बिटमैप ऑब्जेक्ट को ट्रांसफ़र करने में लगता है.

अलग-अलग प्रोसेसर के तौर पर, सीपीयू और जीपीयू में प्रोसेसिंग के लिए अलग-अलग रैम एरिया होते हैं. Android पर बिटमैप ड्रॉ करने पर, सिस्टम बिटमैप को जीपीयू मेमोरी में ट्रांसफ़र करता है. इसके बाद, जीपीयू उसे स्क्रीन पर रेंडर करता है. इसके बाद, जीपीयू बिटमैप को कैश मेमोरी में सेव करता है, ताकि सिस्टम को फिर से डेटा ट्रांसफ़र करने की ज़रूरत न पड़े. ऐसा तब तक होता है, जब तक कि टेक्सचर को जीपीयू टेक्सचर कैश मेमोरी से हटा नहीं दिया जाता.

ध्यान दें: Lollipop डिवाइसों पर, यह स्टेज बैंगनी रंग का होता है.

जब यह सेगमेंट बड़ा हो

किसी फ़्रेम के लिए सभी रिसॉर्स, जीपीयू मेमोरी में सेव होने चाहिए. इसके बाद ही, इन संसाधनों का इस्तेमाल फ़्रेम बनाने के लिए किया जा सकेगा. इसका मतलब है कि इस मेट्रिक के लिए ज़्यादा वैल्यू मिलने का मतलब है कि या तो बहुत कम रिसॉर्स लोड होंगे या बहुत ज़्यादा रिसॉर्स लोड होंगे. आम तौर पर, ऐसा तब होता है, जब कोई ऐप्लिकेशन स्क्रीन के साइज़ के आस-पास का कोई बिटमैप दिखाता है. दूसरा मामला यह है कि जब कोई ऐप्लिकेशन ज़्यादा संख्या में थंबनेल दिखाता है.

इस बार को छोटा करने के लिए, इन तकनीकों का इस्तेमाल किया जा सकता है:

  • यह पक्का करना कि आपके बिट मैप रिज़ॉल्यूशन, दिखाए जाने वाले साइज़ से ज़्यादा बड़े न हों. उदाहरण के लिए, आपके ऐप्लिकेशन को 1024x1024 वाली इमेज को 48x48 वाली इमेज के तौर पर दिखाने से बचना चाहिए.
  • सिंक के अगले चरण से पहले, बिट मैप को एसिंक्रोनस रूप से पहले से अपलोड करने के लिए prepareToDraw() का इस्तेमाल करें.

निर्देश देना

निर्देश जारी करना सेगमेंट से पता चलता है कि स्क्रीन पर डिसप्ले सूचियां दिखाने के लिए, ज़रूरी सभी निर्देश जारी करने में कितना समय लगता है.

सिस्टम, डिसप्ले सूचियों को स्क्रीन पर ड्रॉ करे, इसके लिए जीपीयू को ज़रूरी निर्देश भेज दिए जाते हैं. आम तौर पर, यह कार्रवाई OpenGL ES एपीआई के ज़रिए की जाती है.

इस प्रोसेस में कुछ समय लगता है, क्योंकि सिस्टम जीपीयू को कमांड भेजने से पहले, हर कमांड के लिए आखिरी ट्रांसफ़ॉर्मेशन और क्लिपिंग करता है. इसके बाद, जीपीयू की ओर से अतिरिक्त ओवरहेड पैदा होता है, जो आखिरी निर्देशों का हिसाब लगाता है. इन कमांड में, आखिरी बदलाव और अतिरिक्त क्लिपिंग शामिल होती है.

जब यह सेगमेंट बड़ा हो

इस चरण में लगने वाला समय, डिसप्ले सूचियों की जटिलता और संख्या का सीधा आकलन होता है. सिस्टम, किसी दिए गए फ़्रेम में इन सूचियों को रेंडर करता है. उदाहरण के लिए, कई ड्रॉ ऑपरेशन होने पर, खास तौर पर उन मामलों में जहां हर ड्रॉ प्रिमिटिव की लागत कम होती है, इस समय में बढ़ोतरी हो सकती है. उदाहरण के लिए:

Kotlin

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

Java

for (int i = 0; i < 1000; i++) {
    canvas.drawPoint()
}

जारी करने में इनसे काफ़ी ज़्यादा खर्च आता है:

Kotlin

canvas.drawPoints(thousandPointArray)

Java

canvas.drawPoints(thousandPointArray);

निर्देश देने और डिसप्ले सूचियों को असल में ड्रॉ करने के बीच, हमेशा 1:1 का संबंध नहीं होता. इश्यू कमांड मेट्रिक, जीपीयू को ड्रॉइंग कमांड भेजने में लगने वाले समय को कैप्चर करती है. वहीं, ड्रॉ मेट्रिक, डिसप्ले सूची में दिए गए कमांड को कैप्चर करने में लगने वाले समय को दिखाती है.

यह अंतर इसलिए पैदा होता है, क्योंकि जहां भी संभव होता है वहां सिस्टम की मदद से डिसप्ले सूचियों को कैश मेमोरी में सेव किया जाता है. इस वजह से, ऐसी स्थितियां होती हैं जहां स्क्रॉल, ट्रांसफ़ॉर्म या ऐनिमेशन के लिए, सिस्टम को डिसप्ले सूची को फिर से भेजना पड़ता है. हालांकि, उसे फिर से बनाना नहीं पड़ता. इसके लिए, उसे ड्रॉइंग निर्देशों को फिर से कैप्चर करना पड़ता है. इस वजह से, आपको ड्रॉ करने के निर्देश वाला बार हाई दिखे बिना, “निर्देश दें” वाला बार हाई दिख सकता है.

बफ़र को प्रोसेस करें/स्वैप करें

जब Android, जीपीयू को डिसप्ले सूची सबमिट कर देता है, तो सिस्टम एक आखिरी निर्देश देकर, ग्राफ़िक्स ड्राइवर को बता देता है कि यह सूची मौजूदा फ़्रेम के साथ पूरी हो गई है. इसके बाद, ड्राइवर स्क्रीन पर अपडेट की गई इमेज दिखा सकता है.

जब यह सेगमेंट बड़ा हो

यह समझना ज़रूरी है कि जीपीयू, सीपीयू के साथ मिलकर काम करता है. Android सिस्टम, जीपीयू को ड्रॉ करने के निर्देश देता है. इसके बाद, वह अगले टास्क पर चला जाता है. जीपीयू, सूची में मौजूद ड्रॉ कमांड को पढ़ता है और उन्हें प्रोसेस करता है.

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

इस समस्या को कम करने के लिए, जीपीयू पर होने वाले काम की जटिलता को कम करना है, ठीक उसी तरह जैसे “समस्या से जुड़े निर्देश” वाले चरण के लिए किया जाता है.

अन्य चीज़ें

रेंडरिंग सिस्टम को अपना काम करने में लगने वाले समय के अलावा, काम का एक और सेट मुख्य थ्रेड पर होता है और उसका रेंडरिंग से कोई लेना-देना नहीं है. इस काम में लगने वाले समय को अन्य काम में लगने वाला समय के तौर पर रिपोर्ट किया जाता है. आम तौर पर, दूसरे समय में रेंडर होने में लगने वाला समय, यूज़र इंटरफ़ेस (यूआई) थ्रेड पर होने वाले उस काम को दिखाता है जो रेंडर करने के लगातार दो फ़्रेम के बीच होता है.

जब यह सेगमेंट बड़ा हो

अगर यह वैल्यू ज़्यादा है, तो हो सकता है कि आपके ऐप्लिकेशन में कॉलबैक, इंटेंट या ऐसा कोई अन्य काम हो जो किसी दूसरे थ्रेड पर हो. मेथड ट्रेसिंग या Systrace जैसे टूल, मुख्य थ्रेड पर चल रहे टास्क को देखने की सुविधा दे सकते हैं. इस जानकारी से, परफ़ॉर्मेंस को बेहतर बनाने के लिए टारगेट करने में मदद मिल सकती है.