عملکرد را ارزیابی کنید

از Simpleperf برای ارزیابی عملکرد دستگاه استفاده کنید. Simpleperf یک ابزار پروفایلینگ بومی برای برنامه‌ها و فرآیندهای بومی در اندروید است. از CPU Profiler برای بررسی میزان استفاده از CPU برنامه و فعالیت نخ‌ها به صورت بلادرنگ استفاده کنید.

دو شاخص عملکرد قابل مشاهده توسط کاربر وجود دارد:

  • عملکرد قابل پیش‌بینی و محسوس . آیا رابط کاربری (UI) دچار افت فریم می‌شود یا به طور مداوم با سرعت 60FPS رندر می‌شود؟ آیا صدا بدون مصنوعات یا پرش پخش می‌شود؟ تأخیر بین لمس صفحه توسط کاربر و نمایش اثر آن روی صفحه نمایش چقدر است؟
  • مدت زمان مورد نیاز برای عملیات طولانی‌تر (مانند باز کردن برنامه‌ها).

مورد اول بیشتر از مورد دوم قابل توجه است. کاربران معمولاً متوجه کندی سرعت می‌شوند، اما نمی‌توانند زمان شروع برنامه را بین ۵۰۰ میلی‌ثانیه و ۶۰۰ میلی‌ثانیه تشخیص دهند، مگر اینکه دو دستگاه را در کنار هم ببینند. تأخیر لمسی بلافاصله قابل توجه است و به طور قابل توجهی در درک یک دستگاه نقش دارد.

در نتیجه، در یک دستگاه سریع، خط لوله رابط کاربری (UI pipeline) مهمترین چیز در سیستم است، جدا از آنچه برای حفظ عملکرد خط لوله رابط کاربری ضروری است. این بدان معناست که خط لوله رابط کاربری باید بر هر کار دیگری که برای رابط کاربری روان ضروری نیست، اولویت داشته باشد. برای حفظ یک رابط کاربری روان، همگام‌سازی پس‌زمینه، ارسال اعلان‌ها و کارهای مشابه باید همگی به تعویق بیفتند تا کار رابط کاربری بتواند اجرا شود. می‌توان عملکرد عملیات طولانی‌تر (زمان اجرای HDR+، شروع برنامه و غیره) را برای حفظ یک رابط کاربری روان، معاوضه کرد.

ظرفیت در مقابل لرزش

هنگام بررسی عملکرد دستگاه، ظرفیت و لرزش دو معیار معنادار هستند.

ظرفیت

ظرفیت، کل مقدار منبعی است که دستگاه در طول یک بازه زمانی در اختیار دارد. این می‌تواند منابع CPU، منابع GPU، منابع I/O، منابع شبکه، پهنای باند حافظه یا هر معیار مشابه دیگری باشد. هنگام بررسی عملکرد کل سیستم، می‌توان اجزای جداگانه را جدا کرد و یک معیار واحد را در نظر گرفت که عملکرد را تعیین می‌کند (به خصوص هنگام تنظیم یک دستگاه جدید، زیرا بارهای کاری اجرا شده روی آن دستگاه احتمالاً ثابت هستند).

ظرفیت یک سیستم بسته به منابع محاسباتی آنلاین متفاوت است. تغییر فرکانس CPU/GPU ابزار اصلی تغییر ظرفیت است، اما روش‌های دیگری مانند تغییر تعداد هسته‌های CPU آنلاین نیز وجود دارد. بر این اساس، ظرفیت یک سیستم با مصرف برق مطابقت دارد؛ تغییر ظرفیت همیشه منجر به تغییر مشابهی در مصرف برق می‌شود.

ظرفیت مورد نیاز در یک زمان معین، به طور عمده توسط برنامه در حال اجرا تعیین می‌شود. در نتیجه، پلتفرم نمی‌تواند کار کمی برای تنظیم ظرفیت مورد نیاز برای یک حجم کاری معین انجام دهد و ابزارهای انجام این کار به بهبودهای زمان اجرا (چارچوب اندروید، ART، Bionic، کامپایلر/درایورهای GPU، هسته) محدود می‌شود.

لرزش

اگرچه ظرفیت مورد نیاز برای یک حجم کاری به راحتی قابل مشاهده است، اما جیتر مفهوم مبهم‌تری است. برای آشنایی خوب با جیتر به عنوان مانعی برای سیستم‌های سریع، توصیه می‌کنیم مقاله‌ای با عنوان «مورد عملکرد از دست رفته ابررایانه: دستیابی به عملکرد بهینه در ۸۱۹۲ پردازنده ASCI Q» را مطالعه کنید. (این مقاله بررسی می‌کند که چرا ابررایانه ASCI Q به عملکرد مورد انتظار خود دست نیافت و مقدمه‌ای عالی برای بهینه‌سازی سیستم‌های بزرگ است.)

این صفحه از اصطلاح jitter برای توصیف چیزی استفاده می‌کند که مقاله ASCI Q آن را نویز می‌نامد. jitter رفتار تصادفی سیستم است که مانع از اجرای کار محسوس می‌شود. اغلب کاری است که باید اجرا شود، اما ممکن است الزامات زمان‌بندی دقیقی نداشته باشد که باعث شود در هر زمان خاصی اجرا شود. از آنجا که تصادفی است، رد وجود jitter برای یک حجم کاری مشخص بسیار دشوار است. همچنین اثبات اینکه یک منبع شناخته شده jitter علت یک مشکل عملکردی خاص بوده است، بسیار دشوار است. ابزارهایی که معمولاً برای تشخیص علل jitter (مانند ردیابی یا ثبت وقایع) استفاده می‌شوند، می‌توانند jitter خود را ایجاد کنند.

منابع لرزش (jitter) که در پیاده‌سازی‌های واقعی اندروید تجربه می‌شوند عبارتند از:

  • تأخیر زمان‌بندی
  • کنترل‌کننده‌های وقفه
  • کد درایور برای مدت طولانی در حال اجرا است و preemption یا وقفه‌ها غیرفعال هستند.
  • softirq های طولانی مدت
  • رقابت بر سر قفل (برنامه، چارچوب، درایور هسته، قفل اتصال، قفل mmap)
  • بحث توصیفگر فایل که در آن یک نخ با اولویت پایین، قفل فایل را نگه می‌دارد و از اجرای نخ با اولویت بالا جلوگیری می‌کند.
  • اجرای کد بحرانی رابط کاربری در صف‌های کاری که ممکن است با تأخیر اجرا شوند
  • انتقال‌های حالت بیکاری پردازنده
  • ثبت وقایع
  • تأخیرهای ورودی/خروجی
  • ایجاد فرآیند غیرضروری (برای مثال، پخش‌های CONNECTIVITY_CHANGE )
  • پر شدن بیش از حد حافظه پنهان صفحه ناشی از حافظه آزاد ناکافی

مقدار زمان مورد نیاز برای یک دوره معین از لرزش ممکن است با افزایش ظرفیت کاهش یابد یا کاهش نیابد. به عنوان مثال، اگر یک درایور در حین انتظار برای خواندن از طریق یک گذرگاه i2c، وقفه‌ها را غیرفعال کند، صرف نظر از اینکه CPU در فرکانس ۳۸۴ مگاهرتز یا ۲ گیگاهرتز باشد، زمان ثابتی طول خواهد کشید. افزایش ظرفیت یک راه حل عملی برای بهبود عملکرد در هنگام وجود لرزش نیست. در نتیجه، پردازنده‌های سریع‌تر معمولاً در موقعیت‌های محدود به لرزش، عملکرد را بهبود نمی‌بخشند.

در نهایت، برخلاف ظرفیت، جیتر تقریباً به‌طور کامل در حوزه‌ی اختیار فروشنده‌ی سیستم است.

مصرف حافظه

مصرف حافظه به طور سنتی به عنوان عامل عملکرد ضعیف شناخته می‌شود. اگرچه خود مصرف، یک مشکل عملکردی نیست، اما می‌تواند از طریق سربار lowmemorykiller، راه‌اندازی مجدد سرویس‌ها و thrashing حافظه پنهان صفحه، باعث ایجاد لرزش شود. کاهش مصرف حافظه می‌تواند از علل مستقیم عملکرد ضعیف جلوگیری کند، اما ممکن است بهبودهای هدفمند دیگری نیز وجود داشته باشد که از این علل نیز جلوگیری کند (به عنوان مثال، پین کردن چارچوب برای جلوگیری از خارج شدن آن در زمانی که قرار است به زودی وارد شود).

عملکرد اولیه دستگاه را تجزیه و تحلیل کنید

شروع از یک سیستم کاربردی اما با عملکرد ضعیف و تلاش برای اصلاح رفتار سیستم با بررسی موارد منفرد عملکرد ضعیف قابل مشاهده توسط کاربر، استراتژی مناسبی نیست . از آنجا که عملکرد ضعیف معمولاً به راحتی قابل تکرار نیست (یعنی لرزش) یا مشکل برنامه است، متغیرهای زیاد در کل سیستم مانع از مؤثر بودن این استراتژی می‌شوند. در نتیجه، شناسایی نادرست علل و ایجاد بهبودهای جزئی بسیار آسان است، در حالی که فرصت‌های سیستمی برای اصلاح عملکرد در سراسر سیستم از دست می‌رود.

در عوض، هنگام راه‌اندازی یک دستگاه جدید، از رویکرد کلی زیر استفاده کنید:

  1. سیستم را در حالت رابط کاربری با تمام درایورهای در حال اجرا و برخی تنظیمات اولیه‌ی فرکانس راه‌اندازی کنید (اگر تنظیمات فرکانس را تغییر دادید، تمام مراحل زیر را تکرار کنید).
  2. مطمئن شوید که هسته از نقطه ردیابی sched_blocked_reason و همچنین سایر نقاط ردیابی در خط لوله نمایش که نشان دهنده زمان تحویل فریم به صفحه نمایش هستند، پشتیبانی می‌کند.
  3. در حالی که یک بار کاری سبک و مداوم (مثلاً UiBench یا تست توپ در TouchLatency) را اجرا می‌کنید، ردیابی‌های طولانی از کل خط لوله رابط کاربری (از دریافت ورودی از طریق IRQ تا اسکن نهایی) انجام دهید.
  4. افت فریم شناسایی‌شده در حجم کار سبک و مداوم را برطرف کنید.
  5. مراحل ۳-۴ را تکرار کنید تا بتوانید بدون افت فریم، به مدت بیش از ۲۰ ثانیه به طور همزمان اجرا کنید.
  6. به سراغ سایر منابع آشغال و بی‌ارزش که توسط کاربران قابل مشاهده هستند بروید.

کارهای ساده دیگری که می‌توانید در اوایل معرفی دستگاه انجام دهید عبارتند از:

  • مطمئن شوید که کرنل شما پچ نقطه ردیابی sched_blocked_reason را دارد. این نقطه ردیابی با دسته ردیابی sched در systrace فعال می‌شود و تابعی را فراهم می‌کند که مسئول به خواب رفتن (sleep) هنگام ورود آن رشته به حالت خواب بدون وقفه (uninterruptible sleep) است. این برای تجزیه و تحلیل عملکرد بسیار مهم است زیرا خواب بدون وقفه یک شاخص بسیار رایج از لرزش (jitter) است.
  • مطمئن شوید که ردیابی کافی برای GPU و خطوط لوله نمایشگر دارید. در SOC های اخیر کوالکام، نقاط ردیابی با استفاده از موارد زیر فعال می‌شوند:
  • adb shell "echo 1 > /d/tracing/events/kgsl/enable"
    adb shell "echo 1 > /d/tracing/events/mdss/enable"
    

    این رویدادها هنگام اجرای systrace فعال می‌مانند، بنابراین می‌توانید اطلاعات اضافی در trace مربوط به خط لوله نمایش (MDSS) را در بخش mdss_fb0 مشاهده کنید. در پردازنده‌های Qualcomm SOC، هیچ اطلاعات اضافی در مورد GPU در نمای استاندارد systrace مشاهده نخواهید کرد، اما نتایج در خود trace وجود دارند (برای جزئیات بیشتر، به درک systrace مراجعه کنید).

    چیزی که از این نوع ردیابی نمایشگر می‌خواهید، یک رویداد واحد است که مستقیماً نشان می‌دهد یک فریم به نمایشگر تحویل داده شده است. از آنجا، می‌توانید تعیین کنید که آیا با موفقیت به زمان فریم خود رسیده‌اید یا خیر؛ اگر رویداد X n کمتر از 16.7 میلی‌ثانیه پس از رویداد X n-1 رخ دهد (با فرض نمایشگر 60 هرتز)، پس می‌دانید که jank نکرده‌اید. اگر SOC شما چنین سیگنال‌هایی را ارائه نمی‌دهد، برای دریافت آنها با فروشنده خود همکاری کنید. اشکال‌زدایی لرزش بدون سیگنال قطعی تکمیل فریم بسیار دشوار است.

استفاده از بنچمارک‌های مصنوعی

بنچمارک‌های مصنوعی برای اطمینان از وجود قابلیت‌های اساسی دستگاه مفید هستند. با این حال، در نظر گرفتن بنچمارک‌ها به عنوان معیاری برای عملکرد قابل قبول دستگاه مفید نیست.

بر اساس تجربیات با SOCها، تفاوت در عملکرد بنچمارک مصنوعی بین SOCها با تفاوت مشابه در عملکرد قابل درک رابط کاربری (تعداد فریم‌های از دست رفته، زمان فریم ۹۹ درصد و غیره) همبستگی ندارد. بنچمارک‌های مصنوعی، بنچمارک‌های فقط ظرفیتی هستند؛ لرزش (jitter) تنها با دزدیدن زمان از عملکرد عمده بنچمارک، بر عملکرد اندازه‌گیری شده این بنچمارک‌ها تأثیر می‌گذارد. در نتیجه، نمرات بنچمارک مصنوعی عمدتاً به عنوان معیاری برای عملکرد درک شده توسط کاربر، بی‌ربط هستند.

دو پردازنده‌ی مرکزی (SOC) را در نظر بگیرید که بنچمارک X را اجرا می‌کنند و ۱۰۰۰ فریم از رابط کاربری را رندر می‌کنند و زمان کل رندر را گزارش می‌دهند (نمره پایین‌تر بهتر است).

  • SOC 1 هر فریم از Benchmark X را در 10 میلی‌ثانیه رندر می‌کند و امتیاز 10000 را کسب می‌کند.
  • SOC 2، 99 درصد فریم‌ها را در 1 میلی‌ثانیه و 1 درصد فریم‌ها را در 100 میلی‌ثانیه رندر می‌کند و امتیاز 19900 را کسب می‌کند که امتیازی به طرز چشمگیری بهتر است.

اگر این بنچمارک نشان‌دهنده‌ی عملکرد واقعی رابط کاربری باشد، SOC 2 غیرقابل استفاده خواهد بود. با فرض نرخ نوسازی ۶۰ هرتز، SOC 2 در هر ۱.۵ ثانیه از زمان کار، یک فریم کُند خواهد داشت. در همین حال، SOC 1 (SOC کندتر طبق بنچمارک X) کاملاً روان خواهد بود.

استفاده از گزارش‌های اشکال

گزارش‌های باگ گاهی اوقات برای تحلیل عملکرد مفید هستند، اما از آنجا که بسیار سنگین هستند، به ندرت برای اشکال‌زدایی مشکلات پراکنده‌ی jank مفید هستند. آن‌ها ممکن است نکاتی را در مورد عملکرد سیستم در یک زمان معین ارائه دهند، به خصوص اگر jank در اطراف یک انتقال برنامه باشد (که در یک گزارش باگ ثبت می‌شود). گزارش‌های باگ همچنین می‌توانند نشان دهند که چه زمانی چیزی به طور کلی در سیستم اشتباه است که می‌تواند ظرفیت مؤثر آن را کاهش دهد (مانند کاهش سرعت حرارتی یا قطعه قطعه شدن حافظه).

از TouchLatency استفاده کنید

چندین نمونه از رفتارهای بد از TouchLatency ناشی می‌شود، که بار کاری دوره‌ای ترجیحی مورد استفاده برای Pixel و Pixel XL است. این برنامه در frameworks/base/tests/TouchLatency موجود است و دو حالت دارد: تأخیر لمسی و جهیدن توپ (برای تغییر حالت، روی دکمه گوشه بالا سمت راست کلیک کنید).

تست گوی جهنده دقیقاً به همان سادگی است که به نظر می‌رسد: یک توپ بدون توجه به ورودی کاربر، برای همیشه در صفحه نمایش بالا و پایین می‌پرد. معمولاً اجرای بی‌نقص این تست نیز بسیار دشوار است، اما هرچه به اجرای بدون افت فریم نزدیک‌تر شود، دستگاه شما بهتر خواهد بود. تست گوی جهنده دشوار است زیرا یک حجم کاری جزئی اما کاملاً ثابت است که با کلاک بسیار پایین اجرا می‌شود (این فرض را بر این می‌گذارد که دستگاه دارای یک فرکانس کنترلی است؛ اگر دستگاه با کلاک‌های ثابت کار می‌کند، هنگام اجرای تست گوی جهنده برای اولین بار، کلاک CPU/GPU را تقریباً به حداقل کاهش دهید). با خاموش شدن سیستم و نزدیک شدن کلاک‌ها به حالت بیکار، زمان مورد نیاز CPU/GPU برای هر فریم افزایش می‌یابد. می‌توانید توپ را تماشا کنید و ببینید که همه چیز تکان می‌خورد و همچنین می‌توانید فریم‌های از دست رفته را در systrace مشاهده کنید.

از آنجا که حجم کار بسیار ثابت است، می‌توانید اکثر منابع لرزش را بسیار آسان‌تر از اکثر بارهای کاری قابل مشاهده توسط کاربر، با ردیابی آنچه که دقیقاً در طول هر فریم از دست رفته روی سیستم در حال اجرا است، به جای خط لوله رابط کاربری، شناسایی کنید. کلاک‌های پایین‌تر، با افزایش احتمال اینکه هرگونه لرزش باعث از دست رفتن یک فریم شود، اثرات لرزش را تقویت می‌کنند. در نتیجه، هرچه TouchLatency به 60FPS نزدیک‌تر باشد، احتمال بروز رفتارهای بد سیستم که باعث لرزش‌های پراکنده و دشوار در برنامه‌های بزرگتر می‌شوند، کمتر است.

از آنجایی که لرزش اغلب (اما نه همیشه) وابسته به سرعت کلاک نیست، برای تشخیص لرزش به دلایل زیر از آزمایشی استفاده کنید که در کلاک‌های بسیار پایین اجرا می‌شود:

  • همه جیترها وابسته به سرعت کلاک نیستند؛ بسیاری از منابع فقط زمان پردازنده را مصرف می‌کنند.
  • گاورنر باید با کاهش زمان، میانگین زمان فریم را به مهلت تعیین‌شده نزدیک کند، بنابراین زمان صرف‌شده برای اجرای کارهای غیر رابط کاربری می‌تواند آن را به مرز از دست دادن یک فریم برساند.