Öncelikleri ters çevirmeyi önleme

Bu makalede, Android'in ses sisteminin bunu önlemeye nasıl çalıştığı açıklanmaktadır. öncelik ters çevirme ve kullanabileceğiniz teknikleri vurgulayacağım.

Bu teknikler yüksek performanslı geliştiriciler için faydalı olabilir ses üreten ses uygulamaları, OEM'ler ve SoC sağlayıcıları HAL. Bu tekniklerin uygulanmasının arızaları veya diğer arızaları önlemenin garanti edildiği; özellikle konuşmanın bağlamı dışında kullanılır. Sonuçlar değişiklik gösterebilir, kendi ölçümünüzü yapmalısınız değerlendirme ve test etme sürecidir.

Arka plan

Android AudioFlinger ses sunucusu ve AudioTrack/AudioRecord istemci uygulaması, gecikmeyi azaltmak için yeniden tasarlanıyor. Bu çalışma Android 4.1'de başladı ve diğer iyileştirmelerle devam etti kullanıma sunduk.

Bu daha düşük gecikmeyi elde etmek için sistem genelinde birçok değişiklik yapılması gerekiyordu. Bir en önemli değişiklik, zaman açısından kritik öneme sahip CPU kaynaklarını ileti dizileri, daha öngörülebilir bir planlama politikasına tabi olur. Güvenilir planlama Bu sırada ses arabelleği boyutlarının ve sayılarının azaltılmasına olanak tanır. ve bütçe aşımını önleyebilirsiniz.

Önceliği ters çevirme

Önceliği ters çevirme gerçek zamanlı sistemlerin klasik bir hata modudur. Bu yöntemde, daha yüksek öncelikli bir görev, bekleme süresi boyunca kısıtlanmamış bir süre için engellenir. daha düşük öncelikli bir görevin bir kaynağı serbest bırakması için (örneğin, paylaşılan korunduğu eyalet) a mutex olarak değiştirin.

Bir ses sisteminde önceliğin ters çevirmesi genellikle aksaklık (tıklama, pop, bırakma), tekrarlanan ses devre dışı bıraktığında veya bir komuta yanıt vermekte gecikme yaşayabilirsiniz.

Önceliği ters çevirme için yaygın olarak kullanılan bir geçici çözüm, ses arabelleği boyutlarını artırmaktır. Ancak bu yöntem gecikmeyi artırır ve yalnızca sorunu bir çözüm bulmaktır. Önceliği anlamak ve önlemek daha iyidir ters çevirme işlevini kullanın.

Android ses uygulamasında önceliği ters çevirme bu konumlarda kullanılır. Dolayısıyla, dikkatinizi buraya odaklamanız gerekir:

  • AudioFlinger'da normal mikser iş parçacığı ile hızlı mikser iş parçacığı arasında
  • hızlı bir AudioTrack ve hızlı bir AudioTrack için uygulama geri çağırma hızlı karıştırıcı iş parçacığı (ikisinin de öncelik düzeyi yüksek ancak farklı öncelikler)
  • hızlı bir AudioRecord için uygulama geri çağırma ileti dizisinde hızlı yakalama ileti dizisi (öncekine benzer)
  • ses Donanım Soyutlama Katmanı (HAL) uygulaması, ör. telefon veya yankı giderme için
  • çekirdekteki ses sürücüsü içinde
  • AudioTrack veya AudioRecord geri çağırma ileti dizisi ile diğer uygulama ileti dizileri arasında (Bu durum bizim kontrolümüzde değildir)

Yaygın çözümler

Tipik çözümler şunlardır:

  • kesmeleri devre dışı bırakma
  • öncelikli devralma karşılıklı akımları

Kesmelerin devre dışı bırakılması Linux kullanıcı alanında uygun değildir ve bu program simetrik çok işlemcili cihazlarda (SMP) çalışmaz.

Öncelik devralma futexes (hızlı kullanıcı alanı sessize alma işlemleri) nispeten ağır oldukları için ses sisteminde kullanılmaz. Çünkü onlar da güvenilir bir müşteriye güveniyorlar.

Android'in kullandığı teknikler

"Deneme kilidi" ile başlatılan denemeler ve zaman aşımı ile kilitleyin. Bunlar: karşılıklı dışlama kilidinin engellemeyen ve sınırlı engelleme varyantları işlemidir. Zaman aşımıyla kilitleme ve kilitleme denemesi gayet iyi çalıştı ancak iki tane belirsiz hata moduna açıktır: sunucunun paylaşılan duruma erişmesi garanti edilmediyse istemci meşgul olmuştur ve kümülatif zaman aşımı birbirinden farklı uzun bir kilit dizisi varsa zaman aşımına uğradı.

Ayrıca, atom işlemleri Örneğin:

  • artır
  • bit tabanlı "veya"
  • bit tabanlı "ve"

Bunların tümü önceki değeri döndürür ve gerekli SMP bariyerleri. Dezavantajı ise sınırsız yeniden deneme gerektirmesidir. Uygulamada, yeniden deneme işlemlerinin herhangi bir sorun oluşturmadığını gördük.

Not: Atomik işlemler ve bunların hafıza bariyerleriyle olan etkileşimleri çok yanlış anlaşıldığı ve yanlış kullanıldığı için Bu yöntemler tüm bilgilerin doğru olmasına dikkat edin, ancak şu makaleyi de okumanızı öneririz: Android için SMP Primer konulu videomuzu izleyin.

Yukarıdaki araçların birçoğuna hâlâ sahibiz ve bunları kullanıyoruz. Yakın zamanda şu teknikleri ekledi:

  • Engellemeyen tek okuyuculu tek yazar kullan FIFO sıraları veriler için de geçerlidir.
  • Şunları deneyin: kopyala yerine eyalet paylaş yüksek ile yüksek ile önceliklerini belirleyebilirsiniz.
  • Eyaletin paylaşılması gerektiğinde, durumu maksimum boyut kelime tek otobüslü çalışmayla otomatik olarak erişilebilen bu işlemi yeniden denemeden yapabilirsiniz.
  • Karmaşık çok kelimeli durumlar için durum sırası kullanın. Durum sırası tek okuyuculu, tek yazarlı, engellemeyen bir FIFO yazar daraltması dışında durum için veri yerine kullanılan sıra bitişik itmelerle tek bir itme yapılır.
  • Organizasyondaki bellek bariyerleri gerekir.
  • Güvenin ama doğrulayın. Paylaşırken eyalet dikkat edin, eyaletin iyi bir biçime sahip olduğunu varsayın. Örneğin, bu değerdeki indekslerin emin olmaktır. İleti dizileri arasında bu doğrulama gerekmez karşılıklı güven süreçleri (ortak bir paydada aynı UID'ye sahip olması gerekir). Paydaşlarınızın bilgi paylaşma veriler Örneğin, bozulmanın sonucu olarak ortaya çıkan PCM ses gibi öğeler de dahil edilir.

Engellemeyen algoritmalar

Engellemeyen algoritmalar son zamanlarda yapılan bir araştırmaya konu oldu. Ancak tek okuyuculu tek yazarlı FIFO sıraları hariç karmaşık ve hataya açık olduğunu gördük.

Android 4.2 sürümünden itibaren en iyi uygulamalarımızı Şu konumlarda tek okuyucu/yazar sınıfları:

  • çerçeveler/av/include/media/nbaio/
  • çerçeveler/av/media/libnbaio/
  • çerçeveler/av/services/audioflinger/StateQueue*

Bunlar, AudioFlinger için özel olarak tasarlanmıştır ve emin olun. Engellemeyen algoritmalar, yaygın şekilde zorlaştırır. Bu kodu bir model olarak görebilirsiniz. Ama olabileceğinin farkındayız ve sınıfların, başka amaçlar için de uygun.

Geliştiriciler, örnek OpenSL ES uygulama kodlarının bazıları şu şekilde güncellenmelidir: engellemeyen algoritmalar kullanmalı veya Android dışı açık kaynak bir kitaplığa referans vermelidir.

Bu uygulama için özel olarak tasarlanmış, engellemeyen bir FIFO uygulaması uygulama kodudur. Platform kaynak dizininde bulunan bu dosyalara göz atın frameworks/av/audio_utils:

Araçlar

Bildiğimiz kadarıyla, Google'da özellikle önceliklerin ters çevrilmesini sağlamalısınız. Biraz araştırma statik kod analizi araçları kod tabanının tamamına erişebiliyorsanız tersine çevirme işlemlerini gerçekleştirin. Tabii ki (uygulama için olduğu gibi) rastgele kullanıcı kodu devreye girer veya büyük bir kod tabanı (Linux çekirdeği ve cihaz sürücülerinde olduğu gibi) statik analiz pratik değildir. En önemli şey kodu dikkatlice okuyun ve her şeyin üzerine konuşacağız. Örneğin, sistem izleme ve ps -t -p önceliği tersine çevirdikten sonra görmek açısından yararlıdır ancak size önceden söylemez.

Son söz

Tüm bu konuşmalardan sonra, karşılıklı dışlamadan korkmayın. Eşkenar dörtgenler doğru kullanıldığında ve uygulandığında sıradan kullanıma yönelik arkadaşınız mı? kullanım durumlarında ne kadar önemli olduğunu görebiliriz. Ancak yüksek ve düşük zaman açısından hassas sistemlerde, zaman açısından büyük ihtimalle sorun oluşturacaktır.