Sistem izlemeyi yapılandırarak, Uygulamanızın kısa bir süredeki CPU ve iş parçacığı profili. Sonra Oyununuzun performansını iyileştirmek için sistem izlemesindeki çıktı raporunu kullanabilirsiniz bazı yolları da görmüştük.
Oyuna dayalı sistem izleme kurun
Systrace aracı iki şekilde kullanılabilir:
Systrace aşağıdaki işlemleri yapan alt düzey bir araçtır:
- Kesin referans veriler sağlar. Systrace, çıkışı doğrudan çekirdekten yakalar. yakaladığı metrikler bir dizi metrikle neredeyse aynıdır. raporlanacak.
- Az sayıda kaynak tüketir. Systrace, müşteri tabanının Cihaz, bellek içi arabelleğe veri akışı sağladığından genellikle %1'den azdır.
Optimum ayarlar
Araca makul bir dizi bağımsız değişken vermek önemlidir:
- Kategoriler: Oyun tabanlı bir sistem için etkinleştirilebilecek en iyi kategori grubu
iz şunlardır: {
sched
,freq
,idle
,am
,wm
,gfx
,view
,sync
,binder_driver
,hal
,dalvik
} Arabellek boyutu: Genel bir kural olarak, CPU çekirdeği başına 10 MB arabellek boyutu yaklaşık 20 saniye uzunluğunda bir iz sağlar. Örneğin, bir cihazda iki adet dört çekirdekli CPU (toplam 8 çekirdek),
systrace
programı 80.000 KB (80 MB) boyutundadır.Oyununuzda bağlam değişikliği büyük oranda değişiyorsa arabelleği CPU çekirdeği başına 15 MB'a yükseltin.
Özel etkinlikler: Özel etkinlikler etkinlik bilgilerini etkinleştirdikten sonra,
-a
işaretini kullanarak Systrace'in bu özel etkinlikleri çıktı raporu.
systrace
komut satırını kullanıyorsanız
aşağıdaki komutu kullanın
için en iyi uygulamalara uyan bir sistem izlemesi, yani arabellek ve
ve özel etkinlikler:
python systrace.py -a com.example.myapp -b 80000 -o my_systrace_report.html \ sched freq idle am wm gfx view sync binder_driver hal dalvik
Systrace sistem uygulamasını cihazınız varsa aşağıdaki adımları uygulayarak kategori grubu, arabellek için en iyi uygulamaların geçerli olduğu bir sistem izleme ve özel etkinlikler:
Hata ayıklaması yapılabilecek uygulamaları izle seçeneğini etkinleştirin.
Alıcı: bu ayarı kullanırsanız cihazda 256 MB veya 512 MB kullanılabilir alan olmalıdır ( olup olmadığını kontrol edin ve her 64 MB'lık bellek parçasının ardışık bir parça olarak kullanılabilir.
Kategoriler'i seçin ve ardından aşağıdaki listede bulunan kategorileri etkinleştirin:
am
: Etkinlik Yöneticisibinder_driver
: Bağlayıcı Kernel sürücüsüdalvik
: Dalvik Sanal Makinefreq
: CPU Frekansıgfx
: Grafiklerhal
: Donanım Modülleriidle
: CPU Boştasched
: CPU Planlamasısync
: Senkronizasyonview
: Sistemi Görüntülewm
: Pencere Yöneticisi
Kayıt izleme'yi etkinleştirin.
Oyununuzu yükleyin.
Oyununuzda, oyundaki hangi etkileşimlerin istediğiniz cihaz performansını ayarlayabilirsiniz.
Oyununuzda istenmeyen davranışla karşılaştıktan kısa süre sonra sisteminizi açın. tekrarlandığından emin olun.
Performans istatistiklerini aldınız gereken en önemli şeydir.
Disk alanından tasarruf etmek için cihaz üzerindeki sistem izleri, dosyaları sıkıştırılmış bir izde kaydeder
(*.ctrace
) biçimindedir. Rapor oluştururken bu sıkıştırılmış dosyayı açmak için
komut satırı programına ekleyin ve --from-file
seçeneğini ekleyin:
python systrace.py --from-file=/data/local/traces/my_game_trace.ctrace \ -o my_systrace_report.html
Belirli performans alanlarını iyileştirin
Bu bölümde mobil oyunlarla ilgili yaygın performans endişeleri açıklanmaktadır. , oyununuzun bu yönlerini nasıl tanımlayıp iyileştireceğinizi açıklıyor.
Yükleme hızı
Oyuncular oyununuzun aksiyonuna mümkün olduğunca hızlı bir şekilde yaklaşmak ister. Oyununuzun yüklenme sürelerini mümkün olduğunca iyileştirmek için önemlidir. Aşağıdakiler ölçümler genellikle yükleme sürelerine yardımcı olur:
- Geç yükleme gerçekleştirin. Birbirini izleyen bu öğeleri yalnızca bir kez yükleyin.
- Öğelerinizin boyutunu küçültün. Bu şekilde, paketi sıkıştırılmamış halde bu öğelerin sürümünü oyununuzun APK'sıyla değiştirin.
- Disk açısından verimli bir sıkıştırma yöntemi kullanın. Böyle bir yönteme örnek olarak zlib.
- IL2CPP'yi kullanın kullanın. (Yalnızca Unity kullanıyorsanız geçerlidir.) IL2CPP, çalıştırma performansını artırır.
- Oyununuzu çok iş parçacıklı hale getirin. Daha fazla ayrıntı için bkz. kare hızı tutarlılık bölümüne bakın.
Kare hızı tutarlılığı
Oyun deneyiminin en önemli unsurlarından biri istikrarlı kare hızı. Bu hedefe daha kolay ulaşmak için optimizasyon tekniklerinden bahsedeceğiz.
Çoklu iş parçacığı oluşturma
Birden çok platform için geliştirme yaparken, tüm etkinliklerin tek bir yerden tek bir iş parçacığında. Bu yürütme yöntemi basit olsa da, birçok oyun motorunda uygulamak zor olsa da, Android'de oyun cihazlar. Bunun sonucunda, tek iş parçacıklı oyunlar genellikle yavaş yüklenir ve istikrarlı kare hızı.
Şekil 1'de gösterilen Systrace bir oyunda görülen davranışları gösterir aynı anda yalnızca bir CPU'da çalıştırma:
Oyununuzun performansını iyileştirmek için oyununuzu çok iş parçacıklı hale getirin. Genellikle, en iyi model 2 ileti dizisine sahip olmaktır:
- Oyununuzun ana modüllerini içeren ve oluşturma gönderen bir oyun ileti dizisi komutlarının ikisine katlanır.
- Oluşturma komutlarını alan ve bunları şu dile çeviren bir oluşturma ileti dizisi: grafik komutları.
Vulkan API'si, 2 ortak araç kullanma becerisi nedeniyle bu modeli daha da ileriye taşımaktadır. zaman alabilir. Bu özelliği kullanarak, birden fazla reklam öğesi iş parçacıklarını birden fazla CPU'ya dağıtarak bir sahnenin oluşturma süresini daha da iyileştirir.
Ayrıca, oyununuzun performansını geliştirmek için motora özel değişiklikler çoklu iş parçacığı performansı:
- Oyununuzu Unity oyun motorunu kullanarak geliştiriyorsanız Çok İş Parçalı Oluşturma ve GPU Dış Görünüm seçenekleri.
- Özel oluşturma motoru kullanıyorsanız oluşturma komutunun Ardışık düzen ve grafik komut ardışık düzeni doğru bir şekilde hizalanmalıdır; Aksi takdirde oyununuzdan sahnelerin görüntülenmesinde gecikmelere neden olabilir.
Bu değişiklikleri uyguladıktan sonra oyununuzun en az 2 CPU'yu kullandığını görmeniz gerekir. Şekil 2'de gösterildiği gibi eşzamanlı olarak:
Kullanıcı arayüzü öğesi yükleniyor
Zengin özelliklere sahip bir oyun geliştirirken, çok sayıda farklı seçenek göstermek cazip gelebilir, hem de oyuncuya aynı anda yapmanız gereken bir şeydir. Tutarlı bir kare hızı sağlamak için Ancak, mobil ekranların nispeten küçük boyutunu da göz önünde bulundurmak önemlidir. ve kullanıcı arayüzünüzü olabildiğince basit tutun.
Şekil 3'te gösterilen Systrace raporu, bir mobil cihazın tasarımına göre çok fazla öğe oluşturmaya çalışmak özellikler.
Kullanıcı arayüzü güncelleme süresini 2-3 milisaniyeye düşürmek iyi bir hedeftir. Şunları yapabilirsiniz: aşağıdakine benzer optimizasyonlar gerçekleştirerek bu tür hızlı güncellemeleri elde edebilirsiniz:
- Yalnızca ekrandaki taşınan öğeleri güncelleyin.
- Kullanıcı arayüzü dokularının ve katmanlarının sayısını sınırlayın. Grafik çağrıları, gölgelendiriciler ve dokular gibi farklı öğeler de oluşturabilirsiniz.
- Öğe animasyonu işlemlerini GPU'ya erteleyin.
- Daha agresif engelleme ve örtüşme yöntemleri uygulayın.
- Mümkünse Vulkan API'yi kullanarak çizim işlemleri gerçekleştirin. Çekim çağrısı genel gider daha düşüktür.
Güç tüketimi
Bir önceki bölümde bahsettiğimiz optimizasyonları yaptıktan sonra bile, ilk 45-50 dakika içinde oyununuzun kare hızının düştüğünü önemlidir. Ayrıca cihaz ısınmaya ve daha fazla enerji tüketmeye başlayabilir. yardımcı olabilir.
Birçok durumda, bu istenmeyen termal ve güç tüketimi verileri, ve oyununuzun iş yükünün bir cihazın CPU'ları arasında nasıl dağıtıldığına bağlıdır. Artırmak için uygulamanızın güç tüketimi verimliliğini artırmak için şurada gösterilen en iyi uygulamaları kullanın: bu bölümde bulabilirsiniz.
Bellek açısından yoğun ileti dizilerini tek bir CPU'da tutma
Birçok mobil cihazda L1 önbellekleri belirli CPU'larda, L2 önbelleklerinde ise tek bir saati paylaşan CPU kümelerinde bulunur. L1 önbellek isabetlerini en üst düzeye çıkarmak için genellikle en iyisi, oyununuzun ana iş parçacığını ve tek bir CPU'da çalışan iş parçacıklarıdır.
Kısa süreli işleri düşük güçlü CPU'lara ertele
Unity dahil olmak üzere çoğu oyun motoru, çalışan iş parçacığı işlemlerini Oyununuzun ana iş parçacığına göre farklı bir CPU. Ancak motor mobil cihaz kullanımını düşünen ve oyununuzun üzerinde çalıştığınız programı ya da projeyi kapsar.
Çip üzerinde sistem üzerinde çalışan cihazların çoğunda, biri hızlı CPU'ları ve yavaş CPU'ları içindir. Bunun sonucu Yani, hızlı bir CPU'nun maksimum hızda çalışması gerekiyorsa tüm diğer hızlı CPU'lar da maksimum hızda çalışır.
Şekil 4'te gösterilen örnek rapor, hızlı ve güvenli bir şekilde CPU'lar. Ancak, bu yüksek aktivite seviyesi çok fazla güç ve ısı üretir. pek çok değişiklik yapabilirsiniz.
Genel güç kullanımını azaltmak için planlayıcıya sesin yüklenmesi, çalışan iş parçacıklarının çalıştırılması gibi daha kısa süreli işler koreografiyi yürütüyorum. Bir cihazdaki yavaş CPU'lar kümesi olsun. Bu işi mümkün olduğunca yavaş CPU'lara aktarın ve ekleyebilirsiniz.
Çoğu cihaz yavaş CPU'ları hızlı CPU'lardan önce listeler, ancak cihazınızın SOC'si bu sırayı kullanır. Kontrol etmek için komutlara benzer komutlar çalıştırın bu CPU topoloji keşfinde gösterilmiştir kod bulabilirsiniz.
Hangi CPU'ların cihazınızdaki yavaş CPU'lar olduğunu öğrendikten sonra, kısa süreli mesaj dizileriniz için yakın ilgi alanları (cihazın planlayıcısı) anlatacağım. Bunu yapmak için her bir ileti dizisine aşağıdaki kodu ekleyin:
#include <sched.h> #include <sys/types.h> #include <unistd.h> pid_t my_pid; // PID of the process containing your thread. // Assumes that cpu0, cpu1, cpu2, and cpu3 are the "slow CPUs". cpu_set_t my_cpu_set; CPU_ZERO(&my_cpu_set); CPU_SET(0, &my_cpu_set); CPU_SET(1, &my_cpu_set); CPU_SET(2, &my_cpu_set); CPU_SET(3, &my_cpu_set); sched_setaffinity(my_pid, sizeof(cpu_set_t), &my_cpu_set);
Termal stres
Cihazlar çok ısındığında CPU ve/veya GPU'yu daraltabilir ve bu da beklenmedik şekillerde etkileyen bir problem. Karmaşık grafikler ve yoğun veya sürekli ağ etkinliğinin sorunlarla karşılaşma olasılığı daha yüksektir.
Termal API'yi kullanarak cihazdaki sıcaklık değişikliklerini izleyin ve düşük güç tüketimi ve cihaz sıcaklığının daha düşük olmasını sağlar. Cihaz şunu bildirdiğinde: termal stres, mevcut aktivitelerin azaltılması için güç kullanımı. Örneğin, kare hızını veya poligon mozaiklemeyi azaltın.
İlk olarak PowerManager
nesnesini tanımlayın ve
onCreate()
yönteminde başlatın. Nesneye bir termal durum işleyici ekleyin.
Kotlin
class MainActivity : AppCompatActivity() { lateinit var powerManager: PowerManager override fun onCreate(savedInstanceState: Bundle?) { powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager powerManager.addThermalStatusListener(thermalListener) } }
Java
public class MainActivity extends AppCompatActivity { PowerManager powerManager; @Override protected void onCreate(Bundle savedInstanceState) { ... powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); powerManager.addThermalStatusListener(thermalListener); } }
Dinleyicinin bir durum algıladığında yapılacak işlemleri tanımlayın
unutmayın. Oyununuzda C/C++ kullanılıyorsa şurada termal durum seviyelerine kod ekleyin:
JNI kullanarak yerel oyun kodunuza çağrı yapmak için onThermalStatusChanged()
veya yerel Thermal API'yi kullanabilirsiniz.
Kotlin
val thermalListener = object : PowerManager.OnThermalStatusChangedListener() { override fun onThermalStatusChanged(status: Int) { when (status) { PowerManager.THERMAL_STATUS_NONE -> { // No thermal status, so no action necessary } PowerManager.THERMAL_STATUS_LIGHT -> { // Add code to handle light thermal increase } PowerManager.THERMAL_STATUS_MODERATE -> { // Add code to handle moderate thermal increase } PowerManager.THERMAL_STATUS_SEVERE -> { // Add code to handle severe thermal increase } PowerManager.THERMAL_STATUS_CRITICAL -> { // Add code to handle critical thermal increase } PowerManager.THERMAL_STATUS_EMERGENCY -> { // Add code to handle emergency thermal increase } PowerManager.THERMAL_STATUS_SHUTDOWN -> { // Add code to handle immediate shutdown } } } }
Java
PowerManager.OnThermalStatusChangedListener thermalListener = new PowerManager.OnThermalStatusChangedListener () { @Override public void onThermalStatusChanged(int status) { switch (status) { case PowerManager.THERMAL_STATUS_NONE: // No thermal status, so no action necessary break; case PowerManager.THERMAL_STATUS_LIGHT: // Add code to handle light thermal increase break; case PowerManager.THERMAL_STATUS_MODERATE: // Add code to handle moderate thermal increase break; case PowerManager.THERMAL_STATUS_SEVERE: // Add code to handle severe thermal increase break; case PowerManager.THERMAL_STATUS_CRITICAL: // Add code to handle critical thermal increase break; case PowerManager.THERMAL_STATUS_EMERGENCY: // Add code to handle emergency thermal increase break; case PowerManager.THERMAL_STATUS_SHUTDOWN: // Add code to handle immediate shutdown break; } } };
Dokunmatik ekran gecikmesi
Kareleri mümkün olduğunca hızlı oluşturan oyunlar GPU'ya bağlı bir senaryo oluşturur. kare arabelleği fazla doldurulmaz. CPU'nun GPU'yu beklemesi gerekir. Bu, oyuncunun girişi ile giriş yapan giriş arasında kayda değer bir gecikmeye neden olur ekrandaki efekt.
Oyununuzun kare hızını iyileştirip iyileştiremeyeceğinizi belirlemek için şu adımları uygulayın:
gfx
veinput
kategorilerini içeren bir Systrace raporu oluşturun. Bu kategoriler, dönüşüm oranlarınızın nasıl karşılanacağını belirlemek için dokunmatik ekran gecikmesi.Systrace raporunun
SurfaceView
bölümüne bakın. Tampon fazla doldurulmamış gösterildiği gibi beklemedeki arabellek çizimlerinin sayısı 1 ile 2 arasında bir dalgalanmaya neden olur. (Şekil 5'te):Şekil 5. Şu kadar çok doldurulmuş bir arabellek gösteren Systrace raporu düzenli aralıklarla, çizim komutlarını kabul edemeyecek kadar dolu ziyaret edin.
Kare hızındaki bu tutarsızlığı azaltmak için açıklanan işlemleri tamamlayın aşağıda bulabilirsiniz:
Android Frame Pacing API'sini oyununuza entegre edin
Android Frame Pacing API'si şunları yapmanıza yardımcı olur: Kare değişiklikleri yapın ve oyununuzun belirli bir süreyi koruyacak şekilde bir değiştirme aralığı tanımlayın ve tutarlı bir kare hızına sahip olur.
Oyununuzun kullanıcı arayüzü olmayan öğelerinin çözünürlüğünü azaltın
Modern mobil cihazlardaki ekranlar, bir oynatıcıda bulunandan çok daha fazla piksel içerir. Bu nedenle, 5, hatta 10 piksellik bir çalıştırma için daha düşük örnekleme yapılabilir. bir renk içerir. Çoğu ekran önbelleğinin yapısı düşünüldüğünde, Çözünürlüğü yalnızca bir boyutta azaltın.
Ancak oyununuzun kullanıcı arayüzü öğelerinin çözünürlüğünü azaltmayın. Bu önemli korumak için yeterince büyük bir boyut korumak üzere bu öğelerdeki çizgi kalınlığını korumak tümü için dokunma hedefi boyutu size yardımcı olur.
Düzgün oluşturma
SurfaceFlinger, oyununuzdaki bir sahneyi göstermek için ekran arabelleğine bağlandığından CPU etkinliği anlık olarak artar. CPU etkinliğinde bu ani artışlar meydana gelirse düzensizce, oyununuzda takılma görebilirsiniz. Şekil 6'daki diyagram Bunun nedeni açıklanıyor:
Bir kare, birkaç milisaniye bile geç çizime başlarsa çizimi atlamayabilir sonraki görüntü penceresine geçelim. Ardından kare, bir sonraki Vsync'e kadar beklemelidir. görüntülenir (bir oyunu 30 FPS'de çalıştırırken 33 milisaniye). Bu da Oyuncunun bakış açısından fark edilir düzeyde gecikme yaşanır.
Bu sorunu gidermek için Android Çerçeve İlerlemesi API'yı kullanarak her zaman yeni bir çerçeve VSync dalga önü.
Bellek durumu
Oyununuzu uzun süre çalıştırırken kullanıcıların hata oluşmasına neden olabilir.
Bu durumda, Systrace raporundaki CPU etkinliğini kontrol edin ve ne sıklıkla
sistem kswapd
arka plan programına çağrı yapar. Çok sayıda çağrı varsa
en iyisi, oyununuzun nasıl oynandığına daha yakından bakmak
belleği yönetmek ve temizlemektir.
Daha fazla bilgi için Oyunlarda hafızayı etkili bir şekilde yönetme başlıklı makaleyi inceleyin.
İleti dizisi durumu
Bir Systrace raporunun tipik öğeleri arasında gezinirken, belirli bir ileti dizisinin her olası ileti dizisinde harcadığı süre durumu iş parçacığı (Şekil 7'de gösterildiği gibi) ile uyumludur:
Şekil 7'de gösterildiği gibi, oyununuzun ileti dizilerinin "koşu" veya "çalıştırılabilir" mümkün olduğunca sık olmaları gerekir. Aşağıdaki liste belirli bir ileti dizisinin düzenli olarak gönderilmesine ilişkin yaygın birkaç neden gösterir normal olmayan bir duruma geçiş:
- Bir ileti dizisi uzun süre uyku durumunda kalıyorsa sorun yaşıyor olabilir veya GPU etkinliği bekleme zorluklarından kurtulun.
- Bir ileti dizisi G/Ç'de sürekli olarak engelleniyorsa ya çok fazla veri okuyorsunuzdur veya oyununuz çok bozucu olabilir.
Ek kaynaklar
Oyununuzun performansını iyileştirmeyle ilgili daha fazla bilgi edinmek için aşağıdaki konulara bakın ek kaynaklar:
Videolar
- Oyunlar için Systrace sunumu Android Game Developer Summit 2018'den