Yayınlanma tarihi:
Android 12 (API Düzeyi 31) - Performance ipucu API
Android 13 (API Düzeyi 33) - NDK API'de Performans İpucu Yöneticisi
(Önizleme) Android 15 (DP1) - reportActualWorkDuration()
CPU performansı ipuçlarıyla bir oyun dinamik CPU performansını etkileyebilir daha iyi karşılaması gerekir. Android, çoğu cihazda önceki taleplere göre iş yükü için CPU saat hızı ve çekirdek türü. Bir iş yükü daha fazla CPU kaynağı kullanıyorsa saat hızı yükselir ve zamanla daha büyük bir çekirdeğe taşınır. İş yükünde daha az kaynak Android, kaynak ayırmayı azaltır. ADPF'de uygulama, performansı ve son tarihleri hakkında ek bir sinyal gönderebilir. Bu sistemin daha agresif bir şekilde gelişmesine (performansın iyileşmesine) ve iş yükü tamamlandığında hızlı bir şekilde çalışır (güç kullanımından tasarruf).
Saat hızı
Android cihazlar CPU saat hızını dinamik olarak ayarladığında frekansı da
kodunuzun performansını değiştirin. Dinamik saate yönelik kod tasarlama
hız, performansı en üst düzeye çıkarmak açısından önemlidir.
ve gücü verimli bir şekilde kullanmanız gerekir. CPU frekanslarını doğrudan atayamazsınız
girin. Dolayısıyla, uygulamaların daha yüksek bir hızda çalışmaya çalıştığı yaygın bir yöntem
CPU saat hızları, iş yükünün azaltılması için arka plan iş parçacığında
daha talepkar gibi görünüyor. Bu kötü bir uygulamadır çünkü
güç israfına yol açar ve
ancak uygulama, ekstra enerjiyi kullanmadığında cihazdaki termal yük
kaynaklar. CPU PerformanceHint
API, bu sorunu gidermek için tasarlanmıştır. Ölçüt
gerçek çalışma süresini ve hedef çalışma süresini sisteme bildirmek,
Android, uygulamanın CPU ihtiyaçları hakkında genel bir bakış elde edebilir ve uygulamayı dağıtabilir.
ve kaynakların verimli bir şekilde kullanılmasını sağlar. Bu, verimli güçte optimum performans sağlar
tüketiyoruz.
Çekirdek türleri
Oyununuzun üzerinde çalıştığı CPU çekirdeği türleri de bir diğer önemli performanstır. faktörünü içerir. Android cihazlar genellikle bir iş parçacığına atanan CPU çekirdeğini değiştirir performansa göre dinamik olarak belirleyebilirsiniz. CPU çekirdek ataması birden fazla çekirdek türüne sahip SoC'lerde karmaşıktır. Bu cihazların bazılarında çekirdekler, termal açıdan sürdürülebilir olmayan bir ortama durumu.
Oyununuz aşağıdaki nedenlerden dolayı CPU çekirdeği yakınlığını ayarlamaya çalışmamalıdır:
- İş yükü için en iyi çekirdek türü, cihaz modeline göre değişir.
- Daha büyük çekirdekleri çalıştırmanın sürdürülebilirliği, SoC'ye ve kullandığınız çeşitli her cihaz modelinin sağladığı termal çözümler.
- Termal durum üzerindeki çevresel etki, çekirdekleri daha da karmaşıklaştırabilir. seçim. Örneğin, hava durumu veya telefon kılıfı termal durumu değiştirebilir bir şekilde tanımlar.
- Temel seçim, ek performansa sahip ve ek performansa sahip yeni cihazları barındıramaz. ısısal kapasitedir. Sonuç olarak, cihazlar genellikle bir oyunun işlemcisini yoksayar benzetimidir.
Varsayılan Linux zamanlayıcı davranışı örneği
![Linux Planlayıcısı Davranışı](https://developer.android.com/static/games/optimize/adpf/images/adpf_linux_sched_behavior.png?authuser=19&hl=tr)
PerformanceHint API, DVFS gecikmelerinden daha fazlasını özetliyor
![ADPF Soyutları DVFS Gecikmelerinden daha fazla](https://developer.android.com/static/games/optimize/adpf/images/adpf_dvfs_latency.png?authuser=19&hl=tr)
- Görevlerin belirli bir CPU'da çalışması gerekiyorsa PerformanceHint API sizin adınıza vermeniz gerekir.
- Bu nedenle, yakın ilgi alanı özelliğini kullanmanız gerekmez.
- Cihazlar çeşitli topolojilere sahiptir: Güç ve termal özellikler: uygulama geliştiricilere gösterilemeyecek kadar çeşitlidir.
- Çalıştığınız temel sistem hakkında varsayımlarda bulunamazsınız.
Çözüm
ADPF, PerformanceHintManager
sağlar
oyunların CPU saat hızı ve performans için Android'e performans ipuçları gönderebilmesi
çekirdek türü. Daha sonra işletim sistemi, Çip üzerinde sistem (SoC) ve
cihazın termal çözümü. Uygulamanız, thermal ile birlikte bu API'yi kullanıyorsa
Bu, durum izleme özelliğini kullanmak yerine işletim sistemine daha bilinçli
ipuçları sağlayabilir.
yoğun döngüleri ve kısıtlamaya neden olabilecek diğer kodlama tekniklerini kullanabilirsiniz.
Performans ipuçları oyunda şu şekilde kullanılır:
- Benzer şekilde davranan önemli ileti dizileri için ipucu oturumları oluşturun. Örnek:
- Oluşturma iş parçacığı ve bağımlılıkları bir oturum alır
- Cocos'ta ana motor iş parçacığı ve oluşturma iş parçacığı bir kez oturum
- Unity'de Uyarlanabilir Performans Android Sağlayıcı eklentisini entegre edin
- Unreal'da Unreal Adaptive Performance eklentisini entegre edin ve Birden fazla kalite seviyesini destekleyen ölçeklenebilirlik seçenekleri
- KS ileti dizileri başka bir oturum alıyor
- Sesli mesaj dizileri üçüncü kez ziyaret edildi
- Oluşturma iş parçacığı ve bağımlılıkları bir oturum alır
- Oyun bunu erkenden, en az 2 ms. ve tercihen 4 ms.den yüksek bir sürede yapmalıdır. daha yüksek sistem kaynaklarına ihtiyaç duymadan önce
- Her ipucu oturumunda, her oturumun çalışması için gereken süreyi tahmin edin. Tipik süre bir kare aralığına eşdeğerdir ancak uygulama iş yükü kareler arasında önemli ölçüde farklılık göstermiyorsa daha kısa aralık.
Bu teoriyi pratiğe dökmek için:
PerformanceHintManager'ı başlatın ve createHintSession'ı başlatın
Sistem hizmetini kullanarak yöneticiyi alın ve iş parçacığınız için bir ipucu oturumu oluşturun veya iş parçacığı grubunun aynı iş yükü üzerinde çalışması gerekir.
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);
Gerekirse mesaj dizilerini ayarlayın
Yayınlanma tarihi:
Android 11 (API Düzeyi 34)
setThreads
'ı kullanma
başka iş parçacıklarınız olduğunda PerformanceHintManager.Session
işlevi
bunların daha sonra eklenmesi gerekir. Örneğin, fiziki dersinizi oluşturup
daha sonra oturuma eklemeniz gerekirse bu setThreads
API'yi kullanabilirsiniz.
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);
Daha düşük API Düzeylerini hedefliyorsanız oturumu kaldırmanız ve İleti dizisi kimliklerini değiştirmeniz gerektiğinde yeni bir oturum yeniden oluşturun.
Gerçek Çalışma Süresini Raporla
İşi nanosaniyeler ve rapor halinde tamamlamak için gereken gerçek süreyi takip edin tamamlanmasından sonra da sisteme aktarır. Örneğin, bu, oluşturma iş parçacıklarınız içindir. Her karede bunu çağırın.
Zamanın güvenilir bir şekilde hesaplanması için şunları kullanın:
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();
Örnek:
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);
Gerektiğinde Hedef Çalışma Süresini güncelleme
Hedef çalışma süreniz değiştiğinde, örneğin, oyuncu bir
farklı bir hedef fps'ye sahipse updateTargetWorkDuration
işletim sisteminin kaynakları uygun şekilde ayarlayabilmesi için sisteme
. Her karede çağırmanız gerekmez.
hedef süre değiştiğinde bu parametreyi çağırın.
C++
APerformanceHint_updateTargetWorkDuration(hint_session, target_duration);
Java
hintSession.updateTargetWorkDuration(targetDuration);