প্রোফাইল GPU রেন্ডারিং দিয়ে বিশ্লেষণ করুন

প্রোফাইল GPU রেন্ডারিং টুল পূর্ববর্তী ফ্রেম রেন্ডার করতে রেন্ডারিং পাইপলাইনের প্রতিটি পর্যায়ে যে আপেক্ষিক সময় নেয় তা নির্দেশ করে। এই জ্ঞান আপনাকে পাইপলাইনে বাধা শনাক্ত করতে সাহায্য করতে পারে, যাতে আপনি জানতে পারেন আপনার অ্যাপের রেন্ডারিং কর্মক্ষমতা উন্নত করতে কী অপ্টিমাইজ করতে হবে।

এই পৃষ্ঠাটি সংক্ষিপ্তভাবে ব্যাখ্যা করে যে প্রতিটি পাইপলাইনের পর্যায়ে কী ঘটে এবং সেই সমস্যাগুলি নিয়ে আলোচনা করে যা সেখানে বাধা সৃষ্টি করতে পারে। এই পৃষ্ঠাটি পড়ার আগে, আপনার প্রোফাইল GPU রেন্ডারিং -এ উপস্থাপিত তথ্যের সাথে পরিচিত হওয়া উচিত। এছাড়াও, সমস্ত ধাপগুলি কীভাবে একত্রে ফিট করে তা বোঝার জন্য, রেন্ডারিং পাইপলাইন কীভাবে কাজ করে তা পর্যালোচনা করা সহায়ক হতে পারে।

চাক্ষুষ উপস্থাপনা

প্রোফাইল GPU রেন্ডারিং টুল একটি গ্রাফ আকারে পর্যায় এবং তাদের আপেক্ষিক সময় প্রদর্শন করে: একটি রঙ-কোডেড হিস্টোগ্রাম। চিত্র 1 এই জাতীয় প্রদর্শনের একটি উদাহরণ দেখায়।

চিত্র 1. প্রোফাইল GPU রেন্ডারিং গ্রাফ

প্রোফাইল GPU রেন্ডারিং গ্রাফে প্রদর্শিত প্রতিটি উল্লম্ব বারের প্রতিটি সেগমেন্ট পাইপলাইনের একটি পর্যায়কে উপস্থাপন করে এবং বার গ্রাফে একটি নির্দিষ্ট রঙ ব্যবহার করে হাইলাইট করা হয়। চিত্র 2 প্রতিটি প্রদর্শিত রঙের অর্থের একটি কী দেখায়।

চিত্র 2. প্রোফাইল GPU রেন্ডারিং গ্রাফ লেজেন্ড

একবার আপনি বুঝতে পারবেন যে প্রতিটি রঙ কী বোঝায়, আপনি আপনার অ্যাপ্লিকেশনটির রেন্ডারিং কার্যকারিতা অপ্টিমাইজ করার চেষ্টা করার জন্য নির্দিষ্ট দিকগুলিকে লক্ষ্য করতে পারেন।

পর্যায় এবং তাদের অর্থ

এই বিভাগটি চিত্র 2-এর একটি রঙের সাথে সম্পর্কিত প্রতিটি পর্যায়ে কী ঘটে তা ব্যাখ্যা করে, সেইসাথে বাধার কারণগুলি সন্ধান করতে হবে।

ইনপুট হ্যান্ডলিং

পাইপলাইনের ইনপুট হ্যান্ডলিং স্টেজ পরিমাপ করে যে অ্যাপটি ইনপুট ইভেন্টগুলি পরিচালনা করতে কতক্ষণ ব্যয় করেছে। এই মেট্রিক ইঙ্গিত করে যে অ্যাপটি ইনপুট ইভেন্ট কলব্যাকের ফলে কল করা কোড কার্যকর করতে কতক্ষণ ব্যয় করেছে।

যখন এই সেগমেন্ট বড় হয়

এই ক্ষেত্রে উচ্চ মানগুলি সাধারণত ইনপুট-হ্যান্ডলার ইভেন্ট কলব্যাকের মধ্যে ঘটতে থাকা অত্যধিক পরিশ্রম, বা খুব-জটিল কাজের ফলাফল। যেহেতু এই কলব্যাকগুলি সর্বদা মূল থ্রেডে ঘটে, তাই এই সমস্যার সমাধানগুলি সরাসরি কাজটিকে অপ্টিমাইজ করার উপর ফোকাস করে, বা কাজটিকে অন্য থ্রেডে অফলোড করে।

এটিও লক্ষণীয় যে RecyclerView স্ক্রোলিং এই পর্যায়ে উপস্থিত হতে পারে। RecyclerView যখন স্পর্শ ইভেন্ট গ্রহণ করে তখনই স্ক্রোল করে। ফলস্বরূপ, এটি নতুন আইটেম দৃশ্যগুলিকে স্ফীত বা পপুলেট করতে পারে। এই কারণে, যত তাড়াতাড়ি সম্ভব এই অপারেশন করা গুরুত্বপূর্ণ। ট্রেসভিউ বা সিস্ট্রেসের মতো প্রোফাইলিং টুল আপনাকে আরও তদন্ত করতে সাহায্য করতে পারে।

অ্যানিমেশন

অ্যানিমেশন পর্বটি আপনাকে দেখায় যে সেই ফ্রেমে চলমান সমস্ত অ্যানিমেটর মূল্যায়ন করতে কত সময় লেগেছিল। সবচেয়ে সাধারণ অ্যানিমেটর হল ObjectAnimator , ViewPropertyAnimator এবং Transitions

যখন এই সেগমেন্ট বড় হয়

এই এলাকায় উচ্চ মানগুলি সাধারণত অ্যানিমেশনের কিছু সম্পত্তি পরিবর্তনের কারণে কার্যকর করা কাজের ফলাফল। উদাহরণস্বরূপ, একটি ফ্লিং অ্যানিমেশন, যা আপনার ListView বা RecyclerView স্ক্রোল করে, প্রচুর পরিমাণে দর্শন মুদ্রাস্ফীতি এবং জনসংখ্যা ঘটায়।

পরিমাপ/লেআউট

অ্যান্ড্রয়েড যাতে আপনার ভিউ আইটেমগুলিকে স্ক্রিনে আঁকতে পারে, এটি আপনার ভিউ হায়ারার্কিতে লেআউট এবং ভিউ জুড়ে দুটি নির্দিষ্ট অপারেশন চালায়।

প্রথমত, সিস্টেম ভিউ আইটেম পরিমাপ করে। প্রতিটি ভিউ এবং লেআউটে নির্দিষ্ট ডেটা থাকে যা স্ক্রিনে বস্তুর আকার বর্ণনা করে। কিছু দৃশ্যের একটি নির্দিষ্ট আকার থাকতে পারে; অন্যদের একটি আকার আছে যা প্যারেন্ট লেআউট কন্টেইনারের আকারের সাথে খাপ খায়

দ্বিতীয়ত, সিস্টেম ভিউ আইটেমগুলিকে সাজিয়ে রাখে। একবার সিস্টেম বাচ্চাদের ভিউগুলির মাপ গণনা করে, সিস্টেমটি স্ক্রিনে ভিউগুলির বিন্যাস, আকার এবং অবস্থান নির্ধারণের সাথে এগিয়ে যেতে পারে।

সিস্টেম পরিমাপ এবং বিন্যাস সঞ্চালন শুধুমাত্র দৃষ্টিভঙ্গি আঁকার জন্য নয়, সেই দৃশ্যগুলির মূল শ্রেণিবিন্যাসের জন্যও, সমস্ত পথ রুট ভিউ পর্যন্ত।

যখন এই সেগমেন্ট বড় হয়

যদি আপনার অ্যাপ এই এলাকায় ফ্রেম প্রতি অনেক সময় ব্যয় করে, তাহলে এটি সাধারণত হয় নিছক ভিউয়ের কারণে হয় যা নির্ধারণ করা প্রয়োজন, অথবা আপনার অনুক্রমের ভুল জায়গায় ডবল ট্যাক্সেশনের মতো সমস্যা। এই উভয় ক্ষেত্রেই, কর্মক্ষমতা সম্বোধন করার সাথে আপনার ভিউ শ্রেণীবিন্যাসগুলির কর্মক্ষমতা উন্নত করা জড়িত।

আপনি onLayout(boolean, int, int, int, int) বা onMeasure(int, int) এ যে কোডটি যোগ করেছেন তাও পারফরম্যান্স সমস্যার কারণ হতে পারে। ট্রেসভিউ এবং সিস্ট্রেস আপনাকে কলস্ট্যাকগুলি পরীক্ষা করতে সাহায্য করতে পারে আপনার কোডের সমস্যা চিহ্নিত করতে।

আঁকা

ড্র স্টেজ একটি ভিউ এর রেন্ডারিং ক্রিয়াকলাপকে অনুবাদ করে, যেমন একটি পটভূমি আঁকা বা পাঠ্য অঙ্কন, নেটিভ ড্রয়িং কমান্ডের একটি ক্রমানুসারে। সিস্টেম এই কমান্ডগুলিকে একটি প্রদর্শন তালিকায় ক্যাপচার করে।

ড্র বারটি রেকর্ড করে যে ডিসপ্লে তালিকায় কমান্ডগুলি ক্যাপচার সম্পূর্ণ করতে কতটা সময় লাগে, এই ফ্রেমে স্ক্রীনে আপডেট করার জন্য প্রয়োজনীয় সমস্ত দৃশ্যের জন্য। পরিমাপ করা সময়টি আপনার অ্যাপের UI অবজেক্টে যোগ করা যেকোনো কোডের ক্ষেত্রে প্রযোজ্য। এই ধরনের কোডের উদাহরণ হতে পারে onDraw() , dispatchDraw() , এবং Drawable ক্লাসের সাবক্লাসের অন্তর্গত বিভিন্ন draw ()methods

যখন এই সেগমেন্ট বড় হয়

সরলীকৃত পরিভাষায়, আপনি এই মেট্রিকটি বুঝতে পারবেন যে প্রতিটি অবৈধ দৃশ্যের জন্য onDraw() এ সমস্ত কল চালাতে কত সময় লেগেছে। এই পরিমাপের মধ্যে বাচ্চাদের কাছে ড্র কমান্ড পাঠানোর সময় ব্যয় করা যেকোন সময় এবং উপস্থিত হতে পারে এমন ড্র-এবল অন্তর্ভুক্ত রয়েছে। এই কারণে, আপনি যখন এই বার স্পাইক দেখতে পান, তখন কারণ হতে পারে যে একগুচ্ছ ভিউ হঠাৎ করে অবৈধ হয়ে গেছে। অকার্যকর হলে ভিউ এর ডিসপ্লে তালিকা পুনরুত্থিত করা প্রয়োজন। বিকল্পভাবে, একটি দীর্ঘ সময় কিছু কাস্টম দৃশ্যের ফলাফল হতে পারে যেগুলির onDraw() পদ্ধতিতে কিছু অত্যন্ত জটিল যুক্তি রয়েছে।

সিঙ্ক/আপলোড

সিঙ্ক এবং আপলোড মেট্রিক বর্তমান ফ্রেমের সময় CPU মেমরি থেকে GPU মেমরিতে বিটম্যাপ অবজেক্ট স্থানান্তর করতে যে সময় লাগে তা উপস্থাপন করে।

বিভিন্ন প্রসেসর হিসাবে, সিপিইউ এবং জিপিইউতে প্রক্রিয়াকরণের জন্য নিবেদিত বিভিন্ন র‌্যাম এলাকা রয়েছে। আপনি যখন অ্যান্ড্রয়েডে একটি বিটম্যাপ আঁকেন, তখন GPU স্ক্রিনে রেন্ডার করার আগে সিস্টেমটি বিটম্যাপটিকে GPU মেমরিতে স্থানান্তর করে। তারপর, জিপিইউ বিটম্যাপকে ক্যাশ করে যাতে জিপিইউ টেক্সচার ক্যাশে থেকে টেক্সচারটি উচ্ছেদ না করা পর্যন্ত সিস্টেমটিকে আবার ডেটা স্থানান্তর করার প্রয়োজন হয় না।

দ্রষ্টব্য: ললিপপ ডিভাইসগুলিতে, এই পর্যায়টি বেগুনি।

যখন এই সেগমেন্ট বড় হয়

একটি ফ্রেমের জন্য সমস্ত সংস্থানগুলি একটি ফ্রেম আঁকতে ব্যবহার করার আগে GPU মেমরিতে থাকতে হবে। এর মানে হল যে এই মেট্রিকের জন্য একটি উচ্চ মানের অর্থ হতে পারে বড় সংখ্যক ছোট রিসোর্স লোড বা অল্প সংখ্যক খুব বড় রিসোর্স। একটি সাধারণ ঘটনা হল যখন একটি অ্যাপ একটি একক বিটম্যাপ প্রদর্শন করে যা স্ক্রিনের আকারের কাছাকাছি। আরেকটি ক্ষেত্রে যখন একটি অ্যাপ প্রচুর সংখ্যক থাম্বনেল প্রদর্শন করে।

এই বার সঙ্কুচিত করার জন্য, আপনি কৌশল ব্যবহার করতে পারেন যেমন:

  • আপনার বিটম্যাপ রেজোলিউশনগুলি যে আকারে প্রদর্শিত হবে তার চেয়ে বেশি বড় নয় তা নিশ্চিত করা। উদাহরণস্বরূপ, আপনার অ্যাপের 1024x1024 ইমেজকে 48x48 ইমেজ হিসেবে প্রদর্শন করা এড়িয়ে চলা উচিত।
  • পরবর্তী সিঙ্ক পর্বের আগে অ্যাসিঙ্ক্রোনাসভাবে একটি বিটম্যাপ প্রি-আপলোড করার জন্য prepareToDraw() এর সুবিধা গ্রহণ করে।

আদেশ জারি করুন

ইস্যু কমান্ড সেগমেন্টটি পর্দায় প্রদর্শন তালিকা আঁকার জন্য প্রয়োজনীয় সমস্ত কমান্ড ইস্যু করতে যে সময় নেয় তা উপস্থাপন করে।

সিস্টেমের জন্য স্ক্রিনে প্রদর্শন তালিকা আঁকতে, এটি GPU-তে প্রয়োজনীয় কমান্ড পাঠায়। সাধারণত, এটি OpenGL ES API এর মাধ্যমে এই ক্রিয়াটি সম্পাদন করে।

এই প্রক্রিয়াটি কিছু সময় নেয়, কারণ সিস্টেমটি GPU-তে কমান্ড পাঠানোর আগে প্রতিটি কমান্ডের জন্য চূড়ান্ত রূপান্তর এবং ক্লিপিং করে। অতিরিক্ত ওভারহেড তারপর GPU পাশে দেখা দেয়, যা চূড়ান্ত কমান্ড গণনা করে। এই কমান্ডগুলির মধ্যে চূড়ান্ত রূপান্তর এবং অতিরিক্ত ক্লিপিং অন্তর্ভুক্ত রয়েছে।

যখন এই সেগমেন্ট বড় হয়

এই পর্যায়ে ব্যয় করা সময় হল একটি প্রদত্ত ফ্রেমে সিস্টেম রেন্ডার করা ডিসপ্লে তালিকার জটিলতা এবং পরিমাণের সরাসরি পরিমাপ। উদাহরণস্বরূপ, অনেকগুলি ড্র অপারেশন করা, বিশেষ করে এমন ক্ষেত্রে যেখানে প্রতিটি ড্র প্রাইমিটিভের জন্য একটি ছোট অন্তর্নিহিত খরচ আছে, এই সময় স্ফীত হতে পারে। উদাহরণ স্বরূপ:

কোটলিন

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

জাভা

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

এর চেয়ে ইস্যু করা অনেক বেশি ব্যয়বহুল:

কোটলিন

canvas.drawPoints(thousandPointArray)

জাভা

canvas.drawPoints(thousandPointArray);

কমান্ড ইস্যু করা এবং প্রকৃতপক্ষে ডিসপ্লে তালিকা আঁকার মধ্যে সবসময় 1:1 পারস্পরিক সম্পর্ক থাকে না। ইস্যু কমান্ডের বিপরীতে, যা GPU-তে অঙ্কন কমান্ড পাঠাতে যে সময় নেয় তা ক্যাপচার করে, ড্র মেট্রিক প্রদর্শন তালিকায় জারি করা কমান্ডগুলি ক্যাপচার করতে যে সময় নেয় তা উপস্থাপন করে।

এই পার্থক্যটি দেখা দেয় কারণ ডিসপ্লে তালিকাগুলি যেখানেই সম্ভব সিস্টেম দ্বারা ক্যাশে করা হয়। ফলস্বরূপ, এমন পরিস্থিতি রয়েছে যেখানে একটি স্ক্রোল, ট্রান্সফর্ম বা অ্যানিমেশন সিস্টেমকে একটি ডিসপ্লে তালিকা পুনরায় পাঠাতে হবে, কিন্তু প্রকৃতপক্ষে এটিকে পুনর্নির্মাণ করতে হবে না - স্ক্র্যাচ থেকে অঙ্কন কমান্ডগুলি পুনরুদ্ধার করুন৷ ফলস্বরূপ, আপনি একটি উচ্চ ড্র কমান্ড বার না দেখে একটি উচ্চ "ইস্যু কমান্ড" বার দেখতে পারেন।

প্রক্রিয়া/অদলবদল বাফার

একবার অ্যান্ড্রয়েড তার সমস্ত ডিসপ্লে তালিকা GPU-তে জমা দেওয়া শেষ করে, সিস্টেমটি গ্রাফিক্স ড্রাইভারকে বলতে একটি চূড়ান্ত কমান্ড জারি করে যে এটি বর্তমান ফ্রেমের সাথে সম্পন্ন হয়েছে। এই মুহুর্তে, ড্রাইভার অবশেষে আপডেট করা চিত্রটি স্ক্রিনে উপস্থাপন করতে পারে।

যখন এই সেগমেন্ট বড় হয়

এটা বোঝা গুরুত্বপূর্ণ যে জিপিইউ সিপিইউ-এর সাথে সমান্তরালভাবে কাজ করে। অ্যান্ড্রয়েড সিস্টেম জিপিইউতে কমান্ড ড্র করে এবং তারপরে পরবর্তী টাস্কে চলে যায়। GPU একটি সারি থেকে সেই ড্র কমান্ডগুলি পড়ে এবং সেগুলিকে প্রক্রিয়া করে।

এমন পরিস্থিতিতে যেখানে CPU নির্দেশ জারি করে GPU এর চেয়ে দ্রুত, প্রসেসরের মধ্যে যোগাযোগের সারি পূর্ণ হয়ে যেতে পারে। যখন এটি ঘটে, তখন CPU ব্লক করে এবং পরবর্তী কমান্ড স্থাপনের জন্য সারিতে স্থান না হওয়া পর্যন্ত অপেক্ষা করে। এই পূর্ণ-সারির অবস্থাটি সোয়াপ বাফার পর্যায়ে প্রায়ই দেখা দেয়, কারণ সেই সময়ে, একটি সম্পূর্ণ ফ্রেমের মূল্যের কমান্ড জমা দেওয়া হয়েছে।

এই সমস্যাটি প্রশমিত করার মূল চাবিকাঠি হল GPU-তে কাজের জটিলতা কমানো, আপনি "ইস্যু কমান্ড" পর্বের জন্য যা করবেন একইভাবে।

বিবিধ

রেন্ডারিং সিস্টেমের কাজটি সম্পাদন করতে যে সময় লাগে তার পাশাপাশি, মূল থ্রেডে কাজ করার একটি অতিরিক্ত সেট রয়েছে এবং রেন্ডারিংয়ের সাথে কোন সম্পর্ক নেই। এই কাজটি যে সময় ব্যয় করে তা বিবিধ সময় হিসাবে রিপোর্ট করা হয়। বিবিধ সময় সাধারণত এমন কাজকে প্রতিনিধিত্ব করে যা রেন্ডারিংয়ের পরপর দুটি ফ্রেমের মধ্যে UI থ্রেডে ঘটতে পারে।

যখন এই সেগমেন্ট বড় হয়

যদি এই মানটি বেশি হয়, তাহলে সম্ভবত আপনার অ্যাপে কলব্যাক, অভিপ্রায় বা অন্য কাজ আছে যা অন্য থ্রেডে ঘটতে হবে। মেথড ট্রেসিং বা সিস্ট্রেসের মতো টুলগুলি মূল থ্রেডে চলমান কাজগুলিতে দৃশ্যমানতা প্রদান করতে পারে। এই তথ্য আপনাকে কর্মক্ষমতা উন্নতি লক্ষ্য করতে সাহায্য করতে পারে.