تاريخ الإصدار:
Android 12 (المستوى 31) - واجهة برمجة تطبيقات تلميح الأداء
Android 13 (المستوى 33) - مدير تلميحات الأداء في NDK API
(معاينة) Android 15 (DP1) - reportActualWorkDuration()
مع تعديلات أداء وحدة المعالجة المركزية (CPU)، يمكن للعبة التأثير في أداء وحدة المعالجة المركزية الديناميكية السلوك لتلبية احتياجاته بشكل أفضل. يضبط Android بشكل ديناميكي على معظم الأجهزة. سرعة ساعة وحدة المعالجة المركزية والنوع الأساسي لأعباء العمل بناءً على المتطلبات السابقة. فإذا استهلك عبء العمل المزيد من موارد وحدة المعالجة المركزية (CPU)، تزداد سرعة الساعة وينتقل عبء العمل في النهاية إلى قلب أكبر. إذا كان حجم العمل يستخدم مقدارًا أقل ، فسيخفض Android عملية تخصيص الموارد. باستخدام ADPF، يمكن للتطبيق إشارة إضافية حول أدائها ومواعيدها النهائية هذا النمط ويساعد النظام على زيادة النشاط بشكل أكبر (تحسين الأداء) وخفض بسرعة عند اكتمال أعباء العمل (توفير استخدام الطاقة).
سرعة الساعة
عندما تضبط أجهزة Android سرعة ساعة وحدة المعالجة المركزية (CPU) بشكل ديناميكي، يمكن أن
تغيير أداء التعليمات البرمجية. تصميم التعليمة البرمجية التي تعالج الساعة الديناميكية
والسرعة أمر مهم لتحقيق أفضل أداء والحفاظ على درجة حرارة حرارية آمنة
وحالته واستخدام الطاقة بكفاءة. لا يمكنك تعيين ترددات وحدة المعالجة المركزية مباشرةً
في رمز التطبيق. ونتيجةً لذلك، يمكن للتطبيقات محاولة التشغيل بجودة أعلى
سرعات ساعة وحدة المعالجة المركزية (CPU) هي تشغيل حلقة نشطة في مؤشر ترابط في الخلفية كي لا يتأثّر عبء العمل
أكثر صعوبة. هذه ممارسة سيئة لأنها تهدر الطاقة وتزيد
الحمل الحراري على الجهاز عندما لا يستخدم التطبيق
الموارد. وقد تم تصميم واجهة برمجة التطبيقات CPU PerformanceHint
API لمعالجة هذه المشكلة. من
السماح للنظام بمعرفة مدة العمل الفعلية ومدة العمل المستهدفة،
سيتمكّن Android من الحصول على نظرة عامة على احتياجات وحدة المعالجة المركزية للتطبيق وتخصيصها
الموارد بفعالية. وسيؤدي ذلك إلى الحصول على أفضل أداء عند استخدام طاقة فعّالة.
ومستوى الاستهلاك.
الأنواع الأساسية
إنّ أنواع وحدة المعالجة المركزية (CPU) الأساسية التي تعمل عليها لعبتك هي من الخصائص المهمة الأخرى. . غالبًا ما تغيّر أجهزة Android وحدة المعالجة المركزية (CPU) الأساسية المخصّصة لسلسلة محادثات. بشكل ديناميكي استنادًا إلى سلوك عبء العمل الأخير. إمكانات تعيين وحدة المعالجة المركزية (CPU) الأساسية على منظومة على رقاقة (SoC) بأنواع أساسية متعددة. في بعض هذه الأجهزة، كلما زاد حجم يمكن استخدام النوى لفترة وجيزة فقط بدون التسبب في عجز حراري الولاية.
من المفترض ألّا تحاول لعبتك ضبط إعدادات التقارب الأساسية لوحدة المعالجة المركزية (CPU) للأسباب التالية:
- يختلف أفضل نوع أساسي لأعباء العمل حسب طراز الجهاز.
- تختلف استدامة تشغيل النوى الأكبر حجمًا باختلاف المنظومة على الرقاقة (SoC) ومختلف والحلول الحرارية التي يقدمها كل طراز من الأجهزة
- يمكن أن يؤدي التأثير البيئي على الحالة الحرارية إلى تعقيد نتائج خِيَار. على سبيل المثال، قد تتغيّر حالة الطقس أو حافظة الهاتف الجهاز.
- لا يمكن أن يستوعب الاختيار الأساسي أجهزة جديدة ذات أداء إضافي والقدرات الحرارية. ونتيجةً لذلك، غالبًا ما تتجاهل الأجهزة معالج اللعبة. التقارب.
مثال على سلوك أداة جدولة Linux التلقائية
تستبعد واجهة برمجة التطبيقات PerformanceHint API أكثر من وقت الاستجابة في DVFS.
- إذا كانت هناك حاجة إلى تنفيذ المهام على وحدة معالجة مركزية (CPU) معيّنة، يمكن لواجهة PerformanceHint API معرفة كيفية اتخاذ هذا القرار نيابةً عنك.
- لذلك، لا تحتاج إلى استخدام التقارب.
- تأتي الأجهزة بطوابق مختلفة؛ خصائص القوة والحرارة متنوعة جدًا بحيث لا يمكن عرضها لمطور التطبيق.
- ولا يمكنك وضع أي افتراضات حول النظام الأساسي الذي تعمل عليه.
الحل
ويوفر ADPF PerformanceHintManager
حتى تتمكن الألعاب من إرسال تلميحات عن الأداء إلى Android بشأن سرعة ساعة وحدة المعالجة المركزية (CPU)
النوع الأساسي. يمكن لنظام التشغيل بعد ذلك تحديد أفضل طريقة لاستخدام التلميحات بناءً على تقنية المنظومة على الرقاقة (SoC)
الحل الحراري للجهاز. إذا كان تطبيقك يستخدم واجهة برمجة التطبيقات هذه مع الحرارة
مراقبة الحالة، فيمكنها تقديم المزيد من التلميحات المستنيرة لنظام التشغيل بدلاً من استخدام
والحلقات المشغولة وتقنيات الترميز الأخرى التي يمكن أن تسبب التقييد.
إليك طريقة استخدام اللعبة لتلميحات الأداء:
- إنشاء جلسات تلميحات لسلاسل المحادثات الرئيسية التي تعمل بشكل مشابه مثل:
- تحصل سلسلة المحادثات المعروضة وتبعياتها على جلسة واحدة.
- في Cocos، تحصل سلسلة المحرك الرئيسية وسلسلة المحادثات على واحد الجلسة
- في Unity، يجب دمج المكوّن الإضافي لموفّر نظام التشغيل Android Adaptive Performance
- في Unreal، ادمج المكوّن الإضافي Unreal Adaptive Performance واستخدم خيارات قابلية التوسيع للتوافق مع مستويات جودة متعددة
- تحصل سلاسل محادثات IO على جلسة أخرى
- تحصل سلاسل المحادثات الصوتية على جلسة ثالثة.
- تحصل سلسلة المحادثات المعروضة وتبعياتها على جلسة واحدة.
- يجب أن تجري اللعبة ذلك في وقت مبكر، أي 2 ملي ثانية على الأقل، ويفضّل أن تكون أكثر من 4 ملي ثانية. قبل أن تحتاج الجلسة إلى موارد نظام إضافية.
- في كل جلسة تلميح، يمكنك توقُّع المدة اللازمة لتشغيل كل جلسة. تعادل المدة النموذجية الفاصل الزمني للإطار، ولكن يمكن للتطبيق استخدام فاصل زمني أقصر في حال لم يتفاوت عبء العمل بشكل كبير على مستوى اللقطات.
إليك كيفية وضع النظرية موضع التنفيذ:
إعداد PerformanceHintManager و createHintSession
اطلب من المدير استخدام خدمة النظام وأنشِئ جلسة تلميحية لسلسلة محادثاتك. أو مجموعة سلاسل محادثات تعمل على نفس عبء العمل
C++
int32_t tids[1];
tids[0] = gettid();
int64_t target_fps_nanos = getFpsNanos();
APerformanceHintManager* hint_manager = APerformanceHint_getManager();
APerformanceHintSession* hint_session =
APerformanceHint_createSession(hint_manager, tids, 1, target_fps_nanos);
Java
int[] tids = {
android.os.Process.myTid()
};
long targetFpsNanos = getFpsNanos();
PerformanceHintManager performanceHintManager =
(PerformanceHintManager) this.getSystemService(Context.PERFORMANCE_HINT_SERVICE);
PerformanceHintManager.Session hintSession =
performanceHintManager.createHintSession(tids, targetFpsNanos);
ضبط سلاسل المحادثات إذا لزم الأمر
تاريخ الإصدار:
Android 11 (المستوى 34)
يمكنك استخدام setThreads
.
دالة PerformanceHintManager.Session
عندما يكون لديك سلاسل محادثات أخرى
التي يجب إضافتها لاحقًا. على سبيل المثال، إذا أنشأت خيطًا لعلم الفيزياء
لاحقًا وتحتاج إلى إضافتها إلى الجلسة، يمكنك استخدام واجهة برمجة تطبيقات setThreads
هذه.
C++
auto tids = thread_ids.data();
std::size_t size = thread_ids_.size();
APerformanceHint_setThreads(hint_session, tids, size);
Java
int[] tids = new int[3];
// add all your thread IDs. Remember to use android.os.Process.myTid() as that
// is the linux native thread-id.
// Thread.currentThread().getId() will not work because it is jvm's thread-id.
hintSession.setThreads(tids);
إذا كنت تستهدف مستويات أقل لواجهة برمجة التطبيقات، عليك إلغاء الجلسة يجب إعادة إنشاء جلسة جديدة في كل مرة تحتاج فيها إلى تغيير أرقام تعريف سلاسل المحادثات.
الإبلاغ عن مدة العمل الفعلية
يمكنك تتبّع المدة الفعلية اللازمة لإنجاز العمل بالنانو ثانية وإعداد تقرير. إلى النظام عند الانتهاء من العمل في كل دورة. على سبيل المثال، إذا هذا يخص سلاسل العرض، ويجب استدعائها في كل إطار.
لمعرفة الوقت الفعلي بشكل موثوق، استخدِم:
C++
clock_gettime(CLOCK_MONOTONIC, &clock); // if you prefer "C" way from <time.h>
// or
std::chrono::high_resolution_clock::now(); // if you prefer "C++" way from <chrono>
Java
System.nanoTime();
مثلاً:
C++
// All timings should be from `std::chrono::steady_clock` or `clock_gettime(CLOCK_MONOTONIC, ...)`
auto start_time = std::chrono::high_resolution_clock::now();
// do work
auto end_time = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count();
int64_t actual_duration = static_cast<int64_t>(duration);
APerformanceHint_reportActualWorkDuration(hint_session, actual_duration);
Java
long startTime = System.nanoTime();
// do work
long endTime = System.nanoTime();
long duration = endTime - startTime;
hintSession.reportActualWorkDuration(duration);
تعديل "مدة العمل المستهدفة" عند الضرورة
كلما تغيرت مدة العمل المستهدفة، على سبيل المثال إذا اختار اللاعب
عدد لقطات مستهدَف مختلف في الثانية، عليك طلب updateTargetWorkDuration
لإعلام النظام حتى يتمكن نظام التشغيل من ضبط الموارد وفقًا
على الهدف الجديد. لست مضطرًا إلى استدعائها في كل إطار وعليك فقط
نسميه عند تغيير المدة المستهدفة.
C++
APerformanceHint_updateTargetWorkDuration(hint_session, target_duration);
Java
hintSession.updateTargetWorkDuration(targetDuration);