প্রোফাইল-গাইডেড অপ্টিমাইজেশান (এটি PGO, বা "pogo" নামেও পরিচিত) হল আপনার গেমের অপ্টিমাইজ করা বিল্ডগুলিকে আরও অপ্টিমাইজ করার একটি উপায় যা বাস্তব-জগতে খেলার সময় আপনার গেমটি কীভাবে আচরণ করে সে সম্পর্কে তথ্য ব্যবহার করে৷ এইভাবে, কদাচিৎ চালানো কোড যেমন ত্রুটি বা প্রান্ত-কেসগুলি আপনার কোডের সমালোচনামূলক নির্বাহের পথগুলি থেকে ডি-জোর করা হয়, এটিকে দ্রুত করে।
চিত্র 1. PGO কিভাবে কাজ করে তার একটি ওভারভিউ।
PGO ব্যবহার করার জন্য, আপনি প্রথমে আপনার বিল্ডকে প্রফাইল ডেটা জেনারেট করতে ইন্সট্রুমেন্ট করুন যা কম্পাইলার কাজ করতে পারে। তারপরে আপনি সেই বিল্ডটি চালিয়ে এবং এক বা একাধিক প্রোফাইল ডেটা ফাইল তৈরি করে আপনার কোড অনুশীলন করেন। অবশেষে, আপনি সেই ফাইলগুলিকে ডিভাইস থেকে কপি করুন এবং আপনার ক্যাপচার করা প্রোফাইল তথ্য ব্যবহার করে আপনার এক্সিকিউটেবল অপ্টিমাইজ করতে কম্পাইলারের সাথে ব্যবহার করুন।
পিজিও কাজ ছাড়াই কীভাবে অপ্টিমাইজ করা যায়
প্রোফাইল ডেটা ব্যবহার না করেই অপ্টিমাইজ করা একটি বিল্ড অপ্টিমাইজ করা কোড কীভাবে তৈরি করতে হয় তা নির্ধারণ করার সময় বেশ কয়েকটি হিউরিস্টিক ব্যবহার করে।
কিছু ডেভেলপার দ্বারা স্পষ্টভাবে সংকেত করা হয় - উদাহরণস্বরূপ, C++ 20 বা পরবর্তীতে, শাখা-নির্দেশের ইঙ্গিতগুলি ব্যবহার করে যেমন [[likely]]
এবং [[unlikely]]
। আরেকটি উদাহরণ হতে পারে inline
কীওয়ার্ড ব্যবহার করে, অথবা এমনকি __forceinline
(যদিও সাধারণভাবে, এটি আগেরটির সাথে লেগে থাকা আরও ভালো এবং নমনীয়)। ডিফল্টরূপে, কিছু কম্পাইলার অনুমান করে যে একটি শাখার প্রথম লেগ (অর্থাৎ if
স্টেটমেন্ট, else
অংশ নয়) সম্ভবত একটি। অপ্টিমাইজার কোডের স্ট্যাটিক বিশ্লেষণ থেকে অনুমানও করতে পারে যে এটি কীভাবে কার্যকর হবে - তবে এটি সাধারণত সুযোগের মধ্যে সীমিত।
এই হিউরিস্টিকসের সমস্যা হল যে তারা সমস্ত পরিস্থিতিতে কম্পাইলারকে সঠিকভাবে সাহায্য করতে পারে না - এমনকি সম্পূর্ণ ম্যানুয়াল মার্কআপের সাথেও - তাই যখন তৈরি করা কোডটি সাধারণত ভালভাবে অপ্টিমাইজ করা হয়, তবে কম্পাইলারটি থাকলে এটি ততটা ভাল নয় রানটাইমে এর আচরণ সম্পর্কে আরও তথ্য।
একটি প্রোফাইল তৈরি করা হচ্ছে
যখন আপনার এক্সিকিউটেবলটি ইন্সট্রুমেন্টেড মোডে পিজিও সক্ষম করে তৈরি করা হয়, তখন প্রতিটি কোড ব্লকের শুরুতে আপনার এক্সিকিউটেবলটি কোডের সাথে বর্ধিত হয় - উদাহরণস্বরূপ, একটি ফাংশনের শুরুতে বা একটি শাখার প্রতিটি হাতের শুরুতে। এই কোডটি চলমান কোড দ্বারা ব্লকটি প্রবেশ করার সময় একটি গণনার ট্র্যাক রাখতে ব্যবহৃত হয়, যা কম্পাইলার অপ্টিমাইজড কোড তৈরি করতে পরে ব্যবহার করতে পারে।
কিছু অন্যান্য ট্র্যাকিংও সঞ্চালিত হয় - উদাহরণস্বরূপ, একটি ব্লকে সাধারণ কপি অপারেশনের আকার, যাতে অপারেশনের দ্রুত, ইনলাইনযুক্ত সংস্করণগুলি পরে তৈরি করা যায়।
গেম দ্বারা কিছু ধরণের প্রতিনিধিত্বমূলক কাজ সম্পাদন করার পরে, এক্সিকিউটেবলকে অবশ্যই একটি ফাংশন কল করতে হবে – __llvm_profile_write_file()
– ডিভাইসে একটি কাস্টমাইজযোগ্য অবস্থানে প্রোফাইল ডেটা লিখতে। যখন আপনার বিল্ড কনফিগারেশনে PGO ইন্সট্রুমেন্টেশন সক্রিয় থাকে তখন এই ফাংশনটি আপনার গেমের সাথে স্বয়ংক্রিয়ভাবে লিঙ্ক হয়ে যায়।
লিখিত প্রোফাইল ডেটা ফাইলটি হোস্ট কম্পিউটারে আবার কপি করা উচিত এবং একই বিল্ড থেকে অন্যান্য প্রোফাইলের সাথে একটি অবস্থানে রাখা উচিত যাতে সেগুলি একসাথে ব্যবহার করা যায়।
উদাহরণস্বরূপ, বর্তমান গেমের দৃশ্য শেষ হলে __llvm_profile_write_file()
কল করতে আপনি আপনার গেম কোড পরিবর্তন করতে পারেন। তারপরে, একটি প্রোফাইল নিতে আপনি ইনস্ট্রুমেন্টেশন চালু করে আপনার গেমটি তৈরি করবেন এবং তারপরে এটি আপনার অ্যান্ড্রয়েড ডিভাইসে স্থাপন করবেন। এটি চলাকালীন, প্রোফাইল ডেটা স্বয়ংক্রিয়ভাবে ক্যাপচার করা হয় - আপনার QA প্রকৌশলী গেমের মাধ্যমে চলে, বিভিন্ন পরিস্থিতিতে অনুশীলন করে (বা কেবল তাদের সাধারণ পরীক্ষায় পাস করে)।
আপনি যখন আপনার গেমের বিভিন্ন অংশের অনুশীলন শেষ করেন, আপনি মূল মেনুতে ফিরে যেতে পারেন, যা বর্তমান গেমের দৃশ্যটি শেষ করবে এবং প্রোফাইল ডেটা লিখবে।
তারপরে একটি স্ক্রিপ্ট পরীক্ষা ডিভাইস থেকে প্রোফাইল ডেটা অনুলিপি করতে ব্যবহার করা যেতে পারে এবং এটিকে একটি কেন্দ্রীয় সংগ্রহস্থলে আপলোড করতে পারে যেখানে এটি পরবর্তী ব্যবহারের জন্য ক্যাপচার করা যেতে পারে।
প্রোফাইল ডেটা মার্জিং
একবার একটি ডিভাইস থেকে একটি প্রোফাইল প্রাপ্ত হয়ে গেলে, এটিকে ইনস্ট্রুমেন্টেড বিল্ড দ্বারা তৈরি করা প্রোফাইল ডেটা ফাইল থেকে একটি ফর্মে রূপান্তর করতে হবে যা কম্পাইলার ব্যবহার করতে পারে। AGDE এটি আপনার জন্য স্বয়ংক্রিয়ভাবে করে, আপনার প্রোজেক্টে যোগ করা যেকোন প্রোফাইল ডেটা ফাইলের জন্য।
PGO ডিজাইন করা হয়েছে একাধিক ইন্সট্রুমেন্টেড প্রোফাইলের ফলাফল একত্রে একত্রিত করার জন্য – আপনার যদি একটি প্রজেক্টে একাধিক ফাইল থাকে তাহলে AGDE আপনার জন্য স্বয়ংক্রিয়ভাবে এটি করে।
প্রোফাইল ডেটা সেটগুলি কীভাবে একত্রিত করা কার্যকর হতে পারে তার একটি উদাহরণ হিসাবে, ধরা যাক যে আপনার কাছে QA ইঞ্জিনিয়ারদের একটি ল্যাব ছিল যা আপনার গেমের বিভিন্ন স্তরে খেলছে৷ তাদের প্রতিটি প্লেথ্রু রেকর্ড করা হয়, এবং তারপর আপনার গেমের একটি PGO-ইনস্ট্রুমেন্টেড বিল্ড থেকে প্রোফাইল ডেটা তৈরি করতে ব্যবহৃত হয়। প্রোফাইল মার্জ করা আপনাকে এই সমস্ত ভিন্ন টেস্ট রানের ফলাফলগুলিকে একত্রিত করতে দেয় - যা আপনার কোডের বিভিন্ন অংশ কার্যকর করতে পারে - আরও ভাল ফলাফল দিতে।
আরও ভাল, অনুদৈর্ঘ্য পরীক্ষা করার সময়, যেখানে আপনি অভ্যন্তরীণ রিলিজ থেকে অভ্যন্তরীণ রিলিজে প্রোফাইল ডেটার কপি রাখেন, পুনর্নির্মাণ অগত্যা পুরানো প্রোফাইল ডেটা বাতিল করে না। বেশিরভাগ ক্ষেত্রে, কোড রিলিজ থেকে রিলিজ পর্যন্ত তুলনামূলকভাবে স্থিতিশীল, তাই পুরানো বিল্ড থেকে প্রোফাইল ডেটা এখনও কার্যকর হতে পারে এবং অবিলম্বে বাসি হয়ে যায় না।
প্রোফাইল-গাইডেড অপ্টিমাইজড বিল্ড তৈরি করা হচ্ছে
একবার আপনি আপনার প্রোজেক্টে প্রোফাইল ডেটা যোগ করলে, আপনি আপনার বিল্ড কনফিগারেশনে অপ্টিমাইজেশান মোডে PGO সক্ষম করে আপনার এক্সিকিউটেবল তৈরি করতে এটি ব্যবহার করতে পারেন।
এটি কম্পাইলারের অপ্টিমাইজারকে অপ্টিমাইজেশন সিদ্ধান্ত নেওয়ার সময় আগে ক্যাপচার করা প্রোফাইল ডেটা ব্যবহার করার নির্দেশ দেয়।
কখন প্রোফাইল-গাইডেড অপ্টিমাইজেশান ব্যবহার করবেন
PGO এমন কিছু করার উদ্দেশ্যে নয় যা আপনি বিকাশের শুরুতে বা কোডে প্রতিদিনের পুনরাবৃত্তির সময় সক্ষম করেন। বিকাশের সময় আপনার অ্যালগরিদমিক এবং ডেটা-লেআউট ভিত্তিক অপ্টিমাইজেশানগুলিতে ফোকাস করা উচিত কারণ তারা আপনাকে অনেক বড় সুবিধা দেবে।
PGO বিকাশ প্রক্রিয়ার পরে আসে, যখন আপনি মুক্তির জন্য পলিশ করছেন। প্রোফাইল-গাইডেড অপ্টিমাইজেশানটিকে শীর্ষে থাকা চেরি হিসাবে ভাবুন যা আপনাকে ইতিমধ্যে আপনার কোডটি নিজে অপ্টিমাইজ করার জন্য কিছু সময় ব্যয় করার পরে আপনার কোডের শেষ বিট পারফরম্যান্সটি ছিঁড়ে ফেলতে দেয়৷
PGO এর সাথে প্রত্যাশিত কর্মক্ষমতা উন্নতি
এটি অনেকগুলি কারণের উপর নির্ভর করে, যার মধ্যে রয়েছে আপনার প্রোফাইলগুলি কতটা বিস্তৃত এবং বাসি, এবং একটি ঐতিহ্যগত অপ্টিমাইজ করা বিল্ডের সাথে আপনার কোড কতটা অনুকূল হতে পারে।
সাধারণভাবে, একটি খুব রক্ষণশীল অনুমান হবে যে CPU খরচ মূল থ্রেডগুলিতে ~5% কমবে। আপনি বিভিন্ন ফলাফল দেখতে পারেন.
ইন্সট্রুমেন্টেশন ওভারহেড
PGO-এর যন্ত্রটি ব্যাপক, এবং এটি স্বয়ংক্রিয়ভাবে তৈরি হলেও, এটি বিনামূল্যে নয়। PGO ইন্সট্রুমেন্টেশনের ওভারহেড আপনার কোডবেসের উপর নির্ভর করে পরিবর্তিত হতে পারে।
প্রোফাইল-গাইডেড ইন্সট্রুমেন্টেশনের পারফরম্যান্স খরচ
আপনি ইনস্ট্রুমেন্টেড বিল্ডগুলির সাথে ফ্রেম-রেটের হ্রাস দেখতে পারেন। কিছু ক্ষেত্রে - স্বাভাবিক অপারেশন চলাকালীন আপনার CPU কতটা 100% ব্যবহার করা হয়েছে তার উপর নির্ভর করে - এই ড্রপটি এত বড় হতে পারে যে সাধারণ গেমপ্লেকে কঠিন করে তুলতে পারে।
আমরা সুপারিশ করি যে বেশিরভাগ বিকাশকারীরা তাদের গেমের জন্য একটি আধা-নির্ধারক রিপ্লে মোড তৈরি করে। এই ধরণের কার্যকারিতা আপনার QA টিমকে আপনার গেমের একটি পরিচিত, পুনরাবৃত্তিযোগ্য শুরুর অবস্থানে গেমটি শুরু করার ক্ষমতা দেয় (যেমন একটি সংরক্ষণ গেম বা নির্দিষ্ট পরীক্ষা স্তর), এবং তারপরে তাদের ইনপুট রেকর্ড করে৷ টেস্ট বিল্ড থেকে রেকর্ড করা এই ইনপুটটি একটি পিজিও-ইন্সট্রুমেন্টেড বিল্ডে খাওয়ানো যেতে পারে, প্লেব্যাক করা যেতে পারে এবং একটি পৃথক ফ্রেম প্রক্রিয়া করতে কতক্ষণ সময় লাগে তা নির্বিশেষে বাস্তব-বিশ্বের প্রোফাইল ডেটা তৈরি করা যেতে পারে - এমনকি যদি গেমটি এত ধীর গতিতে চলছিল খেলার অযোগ্য
এই ধরণের কার্যকারিতার অন্যান্য প্রধান সুবিধাও রয়েছে, যেমন পরীক্ষকের প্রচেষ্টাকে গুন করা: একজন পরীক্ষক একটি ডিভাইসে তাদের ইনপুট রেকর্ড করতে পারে এবং তারপর এটি ধোঁয়া পরীক্ষার উদ্দেশ্যে একাধিক বিভিন্ন ধরণের ডিভাইসে চালানো যেতে পারে।
এই ধরনের একটি রিপ্লে সিস্টেম অ্যান্ড্রয়েডে বিশাল সুবিধা পেতে পারে যেখানে ইকোসিস্টেমে প্রচুর সংখ্যক ডিভাইস ভেরিয়েন্ট রয়েছে – এবং সুবিধাগুলি সেখানে শেষ হয় না: এটি আপনার ক্রমাগত ইন্টিগ্রেশন বিল্ড সিস্টেমের একটি মূল অংশও গঠন করতে পারে, যা আপনাকে অনুমতি দেয় নিয়মিত রাতারাতি কর্মক্ষমতা রিগ্রেশন এবং ধোঁয়া পরীক্ষা সঞ্চালন.
রেকর্ডিংটি আপনার গেমের ইনপুট প্রক্রিয়ার মধ্যে সবচেয়ে উপযুক্ত পয়েন্টে ব্যবহারকারীর ইনপুট রেকর্ড করা উচিত (সম্ভবত সরাসরি টাচস্ক্রিন ইভেন্ট নয়, বরং কমান্ড হিসাবে তাদের পরিণতি রেকর্ড করা)। এই ইনপুটগুলিতে এমন একটি ফ্রেম গণনাও থাকা উচিত যা গেমপ্লে চলাকালীন একঘেয়েভাবে টিক আপ করে, যাতে প্লেব্যাকের সময়, রিপ্লে মেকানিজম উপযুক্ত ফ্রেমের জন্য অপেক্ষা করতে পারে যার উপর এটি একটি ইভেন্ট ট্রিগার করবে।
প্লেব্যাক মোডে, আপনার গেমের অনলাইন সাইন-ইন এড়ানো উচিত, বিজ্ঞাপন দেখানো উচিত নয় এবং একটি নির্দিষ্ট টাইমস্টেপে কাজ করা উচিত (আপনার টার্গেট ফ্রেম-রেটে)। আপনি vsync নিষ্ক্রিয় বিবেচনা করা উচিত.
এটা গুরুত্বপূর্ণ নয় যে আপনার গেমের সবকিছু (উদাহরণস্বরূপ, পার্টিকেল সিস্টেম) নিখুঁতভাবে নির্ধারকভাবে পুনরাবৃত্তিযোগ্য, তবে একই ক্রিয়াগুলি একই ইন-গেম ফলাফল এবং ফলাফল প্রদান করা উচিত - অর্থাৎ, গেমপ্লে একই হওয়া উচিত।
প্রোফাইল-গাইডেড ইন্সট্রুমেন্টেশনের মেমরি খরচ
PGO যন্ত্রের মেমরি ওভারহেড নির্দিষ্ট লাইব্রেরির উপর ভিত্তি করে অনেক পরিবর্তিত হয়। আমাদের পরীক্ষায় আমরা ~ 2.2x দ্বারা এক্সিকিউটেবল পরীক্ষার আকারের সামগ্রিক বৃদ্ধি দেখেছি। এই আকার বৃদ্ধির মধ্যে কোড ব্লকের জন্য প্রয়োজনীয় অতিরিক্ত কোড এবং কাউন্টারগুলি সংরক্ষণ করার জন্য প্রয়োজনীয় স্থান উভয়ই অন্তর্ভুক্ত ছিল। এই পরীক্ষাগুলি সম্পূর্ণ ছিল না এবং আপনার অভিজ্ঞতা ভিন্ন হতে পারে।
কখন আপনার প্রোফাইল ডেটা আপডেট বা বাতিল করতে হবে
আপনি যখনই আপনার কোডে (বা গেমের বিষয়বস্তু) একটি বড় পরিবর্তন করবেন তখনই আপনার প্রোফাইল আপডেট করা উচিত।
এর অর্থ কী তা নির্ভর করে আপনার বিল্ড এনভায়রনমেন্টের উপর এবং আপনি কোথায় বিকাশ করছেন।
যেমন আগে উল্লেখ করা হয়েছে, আপনার প্রধান বিল্ড পরিবেশ পরিবর্তন জুড়ে প্রোফাইল ডেটা বহন করা উচিত নয়; যদিও এটি আপনাকে আপনার বিল্ড তৈরি করতে বা ভাঙতে বাধা দেবে না, এটি PGO ব্যবহার করার কার্যকারিতা সুবিধাগুলিকে হ্রাস করবে কারণ খুব কম প্রোফাইল ডেটা নতুন বিল্ড পরিবেশে প্রযোজ্য হবে। যাইহোক, এটি একমাত্র ক্ষেত্রে নয় যেখানে আপনার প্রোফাইল ডেটা বাসি হয়ে যেতে পারে।
চলুন অনুমান করে শুরু করা যাক যে আপনি যখন মুক্তির জন্য প্রস্তুতি নিচ্ছেন তখন বিকাশের শেষের কাছাকাছি না যাওয়া পর্যন্ত আপনি PGO ব্যবহার করবেন না, সাপ্তাহিক ক্যাপচার সংগ্রহের বাইরেও যাতে কর্মক্ষমতা-কেন্দ্রিক প্রকৌশলীরা যাচাই করতে পারেন যে কোনও অপ্রত্যাশিত হেঁচকি থাকবে না। মুক্তির কাছাকাছি।
আপনি যখন আপনার QA টিম প্রতিদিন পরীক্ষা করছেন এবং গেমটি সম্পূর্ণভাবে চালাচ্ছেন তখন আপনি আপনার রিলিজ উইন্ডোর কাছে যাওয়ার সাথে সাথে এটি পরিবর্তিত হয়। এই পর্যায়ে আপনি প্রতিদিন সেই ডেটা থেকে প্রোফাইল তৈরি করতে পারেন, এবং পারফরম্যান্স পরীক্ষার জন্য এবং আপনার নিজস্ব পারফরম্যান্স বাজেট সামঞ্জস্য করার জন্য ভবিষ্যতের বিল্ডগুলি জানাতে সেগুলি ব্যবহার করতে পারেন।
আপনি যখন রিলিজের জন্য প্রস্তুতি নিচ্ছেন, তখন আপনার বিল্ড সংস্করণটি লক করা উচিত যা আপনি প্রকাশ করার পরিকল্পনা করছেন, এবং তারপর আপনার নতুন প্রোফাইল ডেটা তৈরি করে এটির মাধ্যমে QA চালাতে হবে। তারপরে আপনি আপনার এক্সিকিউটেবলের একটি চূড়ান্ত সংস্করণ তৈরি করতে এই ডেটা ব্যবহার করে তৈরি করুন।
QA তারপরে এই অপ্টিমাইজ করা, শিপিং একটি চূড়ান্ত রান-থ্রু তৈরি করতে পারে যাতে এটি প্রকাশ করা ভাল হয়।