این سند به شما نشان میدهد که چگونه با استفاده از ابزارهایی برای شناسایی و رفع گلوگاههای CPU و GPU، عملکرد بازی را بهینه کنید.
بهینهسازی پردازنده
اگر تجزیه و تحلیل نشان دهد که بازی به CPU وابسته است، بررسی بیشتر ضروری است. این امر مستلزم شناسایی رشتهها یا APIهای خاصی است که باعث ایجاد گلوگاه و کاهش FPS میشوند.
برای بهینهسازی پردازنده، یک راهحل جهانی معمولاً مؤثر نیست. در عوض، شما باید بر اساس بازی یا صحنه، سنگینترین حجم کار را شناسایی کنید و سپس منطق و عملکردهای مربوطه را بهینه کنید.
ابزارهای ردیابی زمان موتور بازی
ابزارهای زیر میتوانند در این تحلیل به شما کمک کنند:
بینشهای غیرواقعی
در پروژههای موتور Unreal، ابزار Unreal Insight تجزیه و تحلیل اطلاعات ردیابی زمانبندی را برای رشتههای منفرد تشکیلدهنده یک فریم تسهیل میکند.
به عنوان مثال، GameThread معمولاً بیشترین سهم از زمان CPU را به خود اختصاص میدهد، که عمدتاً به زمان تیک (Tick Time) مربوط میشود. علاوه بر این، بخش قابل توجهی از زمان تیک توسط وظایف مرتبط با FActorComponentTickFunction مصرف میشود.
برای بهینهسازی FActorComponentTick ، ضروری است که محاسبات را حذف کرده و حذف کاراکترها و اشیاء واقع در خارج از میدان دید دوربین را پیادهسازی کنیم. علاوه بر این، استفاده از انیمیشنهای مبتنی بر LOD (سطح جزئیات) میتواند بهبودهای بیشتری در عملکرد ایجاد کند.

پروفایلر یونیتی (یونیتی)
تجزیه و تحلیل با استفاده از Unity Profiler نشان میدهد که Thread اصلی بیش از ۴۵ میلیثانیه زمان مصرف میکند، و PostLateUpdate.FinishFrameRendering با اشغال ۱۶.۲۳ میلیثانیه، آن را به زمانبرترین عملیات تبدیل میکند. در این میان، چندین فراخوانی Inl_RenderCameraStack مشاهده میشود. توصیه میشود که ضرورت فعال بودن دوربینها مشخص شده و بر اساس آن بهینهسازی شوند.

ابزارهای پروفایلینگ در سطح سیستم
از ابزارهای پروفایلینگ زیر استفاده کنید:
پرفتو
با استفاده از Perfetto trace، میتوانید تخصیص هستههای CPU و جزئیات اجرای هر رشته را در یک دستگاه مبتنی بر اندروید تعیین کنید. این به شما امکان میدهد با تجزیه و تحلیل دادههای اجرای رشته، تنگناهای عملکرد را شناسایی کنید.
کیس بالای سر CPU
این ردیابی نشان میدهد که حجم کار روی GameThread و RenderThread باعث ایجاد تأخیر در صف RHI Thread میشود و بر اساس VSync منجر به سناریوی محدود به CPU میشود.

کیس بالای سر پردازنده گرافیکی
این ردیابی نشان میدهد که تکمیل خود GPU از 25 میلیثانیه فراتر رفته است، که نشاندهندهی سناریوی محدود به GPU است.

سیمپلپرف
برای شناسایی توابعی که بیشترین میزان استفاده از CPU را دارند، میتوان از simpleperf استفاده کرد. برای دستیابی به نتایج بهینه، توصیه میشود این توابع را اولویتبندی کرده و ابتدا به توابعی که بیشترین استفاده را دارند، رسیدگی کنید.

Simpleperf به شما کمک میکند تا دادههای مربوط به توابعی را که بیشترین زمان CPU را استفاده میکنند، بررسی کنید. برای بهینهسازی استفاده از CPU، با توابعی که بیشترین CPU را استفاده میکنند شروع کنید. در این مثال، USkeletalMeshComponent که با انیمیشن در ActorComponentTickFunctions مرتبط است، بیشترین CPU را استفاده میکند.
بهینهسازی پردازنده گرافیکی
اگر تجزیه و تحلیل نشان دهد که بازی به GPU وابسته است، بررسی بیشتر ضروری است. این امر مستلزم استفاده از ابزارها و تکنیکهای مختلف برای بهینهسازی و تجزیه و تحلیل GPU است.
برای بهینهسازی پردازنده گرافیکی (GPU)، از یک دیباگر فریم برای تجزیه و تحلیل خط لوله رندر و ترسیم فراخوانیها برای هر صحنه استفاده کنید. همچنین، باید معماری پردازنده گرافیکی (GPU) و رفتار خط لوله را به طور کامل درک کنید تا عملیات یا نواحی غیرضروری برای بهینهسازی را شناسایی کنید.
بخشهای بعدی روشها و ابزارهای بهینهسازی پردازنده گرافیکی (GPU) را توضیح میدهند.
حذف RenderPass های غیرضروری
برای بهبود عملکرد رندر و کاهش بار کاری GPU، رندرهای غیرضروری را حذف کنید. این شامل هر رندری میشود که فاقد فراخوانیهای ترسیم است یا خروجی آن در فریم نهایی استفاده نمیشود.
از یک اشکالزدای GPU، مانند RenderDoc ، برای تجزیه و تحلیل خط لوله رندر و شناسایی فرصتهای بهینهسازی استفاده کنید.
بدون فراخوانیهای ترسیمی (Draw Calls): بررسی کنید که آیا مسیر رندر شامل فراخوانیهای ترسیمی (Draw Calls) است یا خیر. اگر هیچ فراخوانی ترسیمی ندارد، مسیر را حذف کنید.
خروجیهای استفاده نشده: بررسی کنید که آیا مراحل بعدی به خروجیهای مرحله رندر، مثلاً رنگ یا عمق، دسترسی دارند یا آنها را نمایش میدهند یا خیر. اگر این کار را نمیکنند، مرحله را حذف کنید.
گذرگاههای قابل ادغام: گذرگاههایی را که میتوانید ادغام کنید، شناسایی کنید:
- همان فریم بافر یا پیوستها
- عملیات بارگیری یا ذخیره سازی سازگار
- هیچ مانع وابستگی بین آنها وجود ندارد

عملیات بارگیری یا انبار کردن را به حداقل برسانید
عملیات بارگذاری یا ذخیره به دلیل استفاده زیاد از حافظه، منابع زیادی را مصرف میکنند. عملیات بارگذاری-ذخیره غیرضروری را به حداقل برسانید. این اقدامات را فقط زمانی انجام دهید که پیوستها در RenderPass مورد نیاز باشند. در غیر این صورت، آنها را با عملیاتهای Clear یا Don't care جایگزین کنید تا سربار کاهش یابد.
چگونه بهینه سازی کنیم
از یک اشکالزدای GPU، مانند RenderDoc ، برای تجزیه و تحلیل خط لوله رندر و شناسایی فرصتهای بهینهسازی زیر استفاده کنید:
بارگذاری: اگر یک پیوست مرحله رندر از دادههای مرحله یا پیوست قبلی استفاده نکند، عملیات بارگذاری غیرضروری است. در چنین مواردی، استفاده از
Don't careیاClearمیتواند سربار را کاهش دهد.ذخیره: اگر پیوست مرحله رندر پس از مرحله رندر فعلی استفاده نشود، عملیات ذخیره غیرضروری است. در چنین مواردی، از
Don't careیاClearاستفاده کنید.جایگزینی: تعیین کنید که آیا تنظیمات فعلی بارگذاری یا ذخیرهسازی را میتوان با
ClearیاDon't Careبدون تأثیر بر فریم نهایی جایگزین کرد یا خیر.

برای فعال کردن Early-Z از دور انداختن خودداری کنید
Early-Z عملکرد را در پلتفرمهای موبایل بهبود میبخشد. با این حال، یک دستورالعمل discard در یک سایهزن به طور خودکار Early-Z را غیرفعال میکند. اگر دستورالعمل discard ضروری نیست، آن را حذف کنید.
شتاب اولیه-Z
این بهینهسازی به طور قابل توجهی عملیات سایهزن قطعهای را کاهش داده و عملکرد پردازنده گرافیکی (GPU) را بهبود میبخشد.

چگونه بهینه سازی کنیم
از یک اشکالزدای GPU، مانند RenderDoc ، برای تجزیه و تحلیل خط لوله رندر و شناسایی فرصتهای بهینهسازی زیر استفاده کنید:
استفاده از
discardدر سایهزنهای قطعه: کلمه کلیدیdiscardمانع از انجام تستهای عمق اولیه توسط GPU میشود زیرا میزان دید قطعه از قبل مشخص نیست.اصلاح
gl_FragDepth: اصلاح پویایgl_FragDepthعمق یک قطعه را تغییر میدهد، که بهینهسازی Early-Z را غیرفعال میکند زیرا عمق نهایی قبل از پردازش قطعه ناشناخته است.فعال بودن پوشش آلفا به پوشش: وقتی پوشش آلفا به پوشش فعال باشد (که اغلب در رندر MSAA استفاده میشود)، پوشش قطعه به مقادیر آلفا بستگی دارد. این میتواند تست عمق را به تأخیر بیندازد و Early-Z را غیرفعال کند.

بهینه سازی فرمت بافت
انتخاب بهینهی قالب بافت، مصرف حافظه را کاهش میدهد، بهرهوری پهنای باند را افزایش میدهد و عملکرد رندر را بهبود میبخشد. استفاده از قالبهای با دقت بسیار بالا میتواند منابع پردازندهی گرافیکی (GPU) را بدون ارائه مزایای بصری هدر دهد.
چگونه بهینه سازی کنیم
از یک اشکالزدای GPU، مانند RenderDoc ، برای تجزیه و تحلیل خط لوله رندر و شناسایی فرصتهای بهینهسازی زیر استفاده کنید:
- برای بافرهای depth-stencil از
D24S8به جایD32S8استفاده کنید: استفاده ازD24S8برای بافرهای depth-stencil در مقایسه باD32S8، مصرف حافظه را 20٪ کاهش میدهد، بدون اینکه تفاوت قابل توجهی در کیفیت بصری در اکثر برنامهها وجود داشته باشد یا بسیار کم باشد. - استفاده از فشردهسازی
ASTCبرای بافتهای رنگی: فشردهسازیASTCبه طور قابل توجهی استفاده از حافظه بافت را کاهش میدهد - تا 8 برابر در مقایسه با فرمتهای فشرده نشده - در حالی که کیفیت بصری بالا را حفظ میکند. - از فرمتهای نیمشناور به جای تمامشناور استفاده کنید: از
R16FیاRG16Fبرای کاهش پهنای باند حافظه و مصرف فضای ذخیرهسازی استفاده کنید. این فرمتها برای بافرهای پسپردازش بسیار مناسب هستند.
بهینهسازی پیچیدگی هندسه
به حداقل رساندن پیچیدگی هندسی، عملکرد رندرینگ را بهبود میبخشد، به خصوص در دستگاههای تلفن همراه با قابلیتهای محدود GPU. این شامل استفاده از تعداد کمتری از رئوس و مثلثها، ادغام اشیاء برای کاهش فراخوانیهای ترسیم و حذف هندسه رندر نشده یا غیرضروری است. تکنیکهایی مانند سادهسازی مش، سطح جزئیات (LOD) و حذف frustum یا occlusion میتواند به طور قابل توجهی بار کاری GPU را کاهش داده و نرخ فریم را افزایش دهد.
چگونه بهینه سازی کنیم
از ابزارهای پروفایلینگ و اشکالزداهای GPU مانند RenderDoc ، Android GPU Inspector یا سایر تحلیلگرهای عملکرد برای شناسایی گلوگاههای عملکرد مرتبط با هندسه استفاده کنید.
کاهش تعداد مثلثها: استفاده از چندضلعیها را به حداقل برسانید، به خصوص برای اشیاء کوچک یا دور.
استفاده از سطح جزئیات (LOD): بر اساس فاصله دوربین، مشهای سادهتر به طور خودکار استفاده میشوند.
ادغام مشهای کوچک: اشیاء ثابت را تجمیع کنید تا فراخوانیهای ترسیم و سربار CPU کاهش یابد.
حذف ناقص و انسداد: از رندر کردن اشیایی که خارج از دید هستند یا توسط عناصر دیگر پنهان شدهاند، خودداری کنید.
پیوستهای غیرضروری را حذف کنید
پیوستهای رندر (مثلاً رنگ، عمق، شابلون) پهنای باند حافظه و منابع GPU را مصرف میکنند، حتی اگر استفاده نشوند. حذف پیوستهای غیرضروری یا اضافی، عملکرد را بهبود میبخشد و مصرف برق را کاهش میدهد، بهویژه در پلتفرمهای موبایل.
چگونه بهینه سازی کنیم
از ابزارهای پروفایلینگ و اشکالزداهای GPU مانند RenderDoc ، Android GPU Inspector یا سایر تحلیلگرهای عملکرد برای شناسایی گلوگاههای عملکرد مرتبط با هندسه استفاده کنید.
- میزان استفاده واقعی را بررسی کنید: آیا فراخوانیهای ترسیمی یا سایهزنهایی وجود دارند که در حال نوشتن یا خواندن از فایل پیوست باشند؟
- تحلیل خروجی فریم:
RenderDocیا ابزارهای مشابه برای تعیین اینکه آیا فایل پیوست در تصویر نهایی نقش دارد یا خیر، استفاده کنید. - پیوستهای موقت یا ساختگی را در نظر بگیرید: پیوستهای موقت یا عملیات ذخیرهسازی «اهمیت ندهید» باید برای دادههای موقت که نیازی به ذخیرهسازی مداوم ندارند، استفاده شوند.
بهینه سازی دقت سایه زن
استفاده از دقت بیش از حد بالا (برای مثال، highp به جای mediump یا lowp ) در سایهزنها، حجم کار GPU، مصرف برق و فشار بر رجیستر را افزایش میدهد، به خصوص در GPUهای موبایل. با استفاده از کمترین دقت کافی برای متغیرها (برای مثال، موقعیتها، رنگها، UVها)، میتوانید عملکرد را بدون تأثیر بصری قابل تشخیص بهبود بخشید.

چگونه بهینه سازی کنیم
از ابزارهای پروفایلینگ و اشکالزداهای GPU مانند RenderDoc، Android GPU Inspector یا سایر تحلیلگرهای عملکرد برای شناسایی گلوگاههای عملکرد مرتبط با هندسه استفاده کنید.
بررسی کد سایهزن: متغیرهای سایهزن را ارزیابی کنید و تأیید کنید که دقت بالا فقط در صورت لزوم، مانند محاسبات عمق یا فضای صفحه، استفاده میشود. برای رنگها، مختصات UV یا مقادیری که به دقت بالا نیاز ندارند، از دقت متوسط یا کم استفاده کنید.
استفاده از اشکالزداهای پردازنده گرافیکی (GPU debuggers): ابزارهای تشخیصی، مانند RenderDoc یا پروفایلرهای پردازنده گرافیکی موبایل (برای مثال، AGI، Mali/GPU Inspector)، استفاده از رجیستر بالا یا توقفهای سایهزن مرتبط با مشکلات دقت را شناسایی میکنند.

فعال کردن حذف از پشت صفحه
رندر کردن مثلثهایی که پشت به دوربین هستند (back-faces) اغلب برای اشیاء جامد غیرضروری است.
چگونه بهینه سازی کنیم
استفاده از VK_CULL_MODE_NONE میتواند تأثیر منفی بر عملکرد داشته باشد، زیرا GPU را مجبور میکند تا هم سطوح جلویی و هم سطوح پشتی را رندر کند، که این امر حجم کار رندر را افزایش میدهد.

به حداقل رساندن overdraw در صحنههای رابط کاربری
حذف فراخوانیهای ترسیم و رندرهای غیرضروری، بهویژه در صحنههای رابط کاربری، برای افزایش عملکرد رندر و کاهش بار کاری پردازنده گرافیکی. بهعنوان مثال، در یک صحنه رابط کاربری که کل جهان قبل از پوشش رابط کاربری در سراسر صفحه رندر میشود، رندر جهان زائد میشود.
چگونه بهینه سازی کنیم
از یک اشکالزدای GPU، مانند RenderDoc ، برای تجزیه و تحلیل خط لوله رندر و شناسایی فرصتهای بهینهسازی زیر استفاده کنید:
- عدم وجود overdraw اضافی را تأیید کنید. در زمینههای رابط کاربری، که ممکن است کل صفحه نمایش رندر شود، تأیید کنید که مراحل رندر قبلی بیجهت overdraw نشده باشند.
- برای بهینهسازی عملکرد، تست عمقی و حذف را فعال کنید.
- ترتیب رندر را از جلو به عقب در نظر بگیرید.
