Kontributor latensi audio

Halaman ini berfokus pada kontributor latensi keluaran, namun diskusi serupa juga berlaku untuk latensi masukan.

Dengan asumsi sirkuit analog tidak memberikan kontribusi yang signifikan, maka kontributor utama tingkat permukaan terhadap latensi audio adalah sebagai berikut:

  • Aplikasi
  • Jumlah total buffer dalam pipa
  • Ukuran setiap buffer, dalam frame
  • Latensi tambahan setelah pemroses aplikasi, seperti dari DSP

Meskipun daftar kontributor di atas akurat, daftar ini juga menyesatkan. Alasannya adalah jumlah buffer dan ukuran buffer lebih merupakan akibat daripada penyebab . Apa yang biasanya terjadi adalah skema buffer tertentu diimplementasikan dan diuji, namun selama pengujian, audio yang underrun atau overrun terdengar sebagai "klik" atau "pop". Untuk mengimbanginya, perancang sistem kemudian meningkatkan ukuran buffer atau jumlah buffer. Hal ini memberikan hasil yang diinginkan yaitu menghilangkan underruns atau overruns, namun juga memiliki efek samping yang tidak diinginkan yaitu peningkatan latensi. Untuk informasi selengkapnya tentang ukuran buffer, lihat video Latensi audio: ukuran buffer .

Pendekatan yang lebih baik adalah memahami penyebab underruns dan overruns, lalu memperbaikinya. Hal ini menghilangkan artefak suara dan memungkinkan buffer yang lebih kecil atau lebih sedikit sehingga mengurangi latensi.

Berdasarkan pengalaman kami, penyebab paling umum dari underruns dan overruns meliputi:

  • Linux CFS (Penjadwal yang Sepenuhnya Adil)
  • thread prioritas tinggi dengan penjadwalan SCHED_FIFO
  • inversi prioritas
  • latensi penjadwalan yang panjang
  • penangan interupsi yang sudah berjalan lama
  • waktu penonaktifan interupsi yang lama
  • manajemen daya
  • kernel keamanan

Penjadwalan Linux CFS dan SCHED_FIFO

Linux CFS dirancang agar adil terhadap beban kerja bersaing yang berbagi sumber daya CPU yang sama. Keadilan ini diwakili oleh parameter Nice per-thread. Nilai Nice berkisar dari -19 (paling tidak bagus, atau alokasi waktu CPU terbanyak) hingga 20 (alokasi waktu CPU paling bagus, atau paling sedikit). Secara umum, semua thread dengan nilai Nice tertentu menerima waktu CPU yang kira-kira sama dan thread dengan nilai Nice yang lebih rendah secara numerik akan menerima lebih banyak waktu CPU. Namun, CFS “adil” hanya dalam jangka waktu observasi yang relatif lama. Selama periode observasi jangka pendek, CFS dapat mengalokasikan sumber daya CPU dengan cara yang tidak terduga. Misalnya, ini mungkin memindahkan CPU dari thread dengan kualitas yang rendah ke thread dengan kualitas yang tinggi. Dalam hal audio, hal ini dapat mengakibatkan underrun atau overrun.

Solusi yang jelas adalah menghindari CFS untuk thread audio performa tinggi. Mulai Android 4.1, thread tersebut sekarang menggunakan kebijakan penjadwalan SCHED_FIFO , bukan kebijakan penjadwalan SCHED_NORMAL (juga disebut SCHED_OTHER ) yang diterapkan oleh CFS.

Prioritas SCHED_FIFO

Meskipun thread audio performa tinggi sekarang menggunakan SCHED_FIFO , thread tersebut masih rentan terhadap thread SCHED_FIFO dengan prioritas lebih tinggi lainnya. Ini biasanya merupakan thread pekerja kernel, tetapi mungkin juga ada beberapa thread pengguna non-audio dengan kebijakan SCHED_FIFO . Prioritas SCHED_FIFO yang tersedia berkisar dari 1 hingga 99. Thread audio berjalan pada prioritas 2 atau 3. Hal ini membuat prioritas 1 tersedia untuk thread dengan prioritas lebih rendah, dan prioritas 4 hingga 99 untuk thread dengan prioritas lebih tinggi. Kami menyarankan Anda menggunakan prioritas 1 bila memungkinkan, dan mencadangkan prioritas 4 hingga 99 untuk thread yang dijamin selesai dalam jangka waktu terbatas, dijalankan dengan periode lebih pendek dari periode thread audio, dan diketahui tidak mengganggu penjadwalan rangkaian audio.

Penjadwalan tarif-monotonik

Untuk informasi lebih lanjut tentang teori penetapan prioritas tetap, lihat artikel Wikipedia Penjadwalan rate-monotonic (RMS). Poin utamanya adalah bahwa prioritas tetap harus dialokasikan secara ketat berdasarkan periode, dengan prioritas yang lebih tinggi diberikan pada rangkaian periode yang lebih pendek, bukan berdasarkan pada anggapan “pentingnya”. Thread non-periodik dapat dimodelkan sebagai thread periodik, menggunakan frekuensi eksekusi maksimum dan komputasi maksimum per eksekusi. Jika thread non-periodik tidak dapat dimodelkan sebagai thread periodik (misalnya thread dapat dieksekusi dengan frekuensi tidak terbatas atau komputasi per eksekusi tidak terbatas), maka thread tersebut tidak boleh diberi prioritas tetap karena hal tersebut tidak sesuai dengan penjadwalan thread periodik yang sebenarnya. .

Pembalikan prioritas

Inversi prioritas adalah mode kegagalan klasik sistem waktu nyata, di mana tugas dengan prioritas lebih tinggi diblokir untuk waktu yang tidak terbatas menunggu tugas dengan prioritas lebih rendah melepaskan sumber daya seperti (keadaan bersama yang dilindungi oleh) mutex . Lihat artikel " Menghindari inversi prioritas " untuk mengetahui teknik mitigasinya.

Penjadwalan latensi

Latensi penjadwalan adalah waktu antara saat thread siap dijalankan dan saat peralihan konteks yang dihasilkan selesai sehingga thread benar-benar berjalan di CPU. Semakin pendek latensinya, semakin baik, dan lebih dari dua milidetik akan menyebabkan masalah pada audio. Latensi penjadwalan yang panjang kemungkinan besar terjadi selama transisi mode, seperti menghidupkan atau mematikan CPU, beralih antara kernel keamanan dan kernel normal, beralih dari mode daya penuh ke mode daya rendah, atau menyesuaikan frekuensi dan voltase jam CPU .

Interupsi

Dalam banyak desain, CPU 0 melayani semua interupsi eksternal. Jadi pengendali interupsi yang berjalan lama mungkin menunda interupsi lainnya, khususnya interupsi penyelesaian akses memori langsung audio (DMA). Rancang penangan interupsi untuk menyelesaikan dengan cepat dan menunda pekerjaan yang panjang pada sebuah thread (sebaiknya thread CFS atau thread SCHED_FIFO prioritas 1).

Demikian pula, menonaktifkan interupsi pada CPU 0 untuk jangka waktu lama memiliki akibat yang sama yaitu menunda layanan interupsi audio. Waktu penonaktifan interupsi yang lama biasanya terjadi saat menunggu kunci putaran kernel. Tinjau kunci putaran ini untuk memastikannya dibatasi.

Daya, kinerja, dan manajemen termal

Manajemen daya adalah istilah luas yang mencakup upaya untuk memantau dan mengurangi konsumsi daya sekaligus mengoptimalkan kinerja. Manajemen termal dan pendinginan komputer serupa tetapi berupaya mengukur dan mengontrol panas untuk menghindari kerusakan akibat panas berlebih. Di kernel Linux, gubernur CPU bertanggung jawab atas kebijakan tingkat rendah, sementara mode pengguna mengonfigurasi kebijakan tingkat tinggi. Teknik yang digunakan meliputi:

  • penskalaan tegangan dinamis
  • penskalaan frekuensi dinamis
  • pengaktifan inti dinamis
  • peralihan cluster
  • gerbang listrik
  • hotplug (hotswap)
  • berbagai mode tidur (berhenti, berhenti, diam, tunda, dll.)
  • migrasi proses
  • afinitas prosesor

Beberapa operasi manajemen dapat mengakibatkan "penghentian kerja" atau waktu di mana tidak ada pekerjaan berguna yang dilakukan oleh pemroses aplikasi. Penghentian pekerjaan ini dapat mengganggu audio, sehingga pengelolaan tersebut harus dirancang untuk penghentian pekerjaan dalam kasus terburuk yang dapat diterima saat audio aktif. Tentu saja, ketika pelarian termal sudah dekat, menghindari kerusakan permanen lebih penting daripada audio!

Kernel keamanan

Kernel keamanan untuk Manajemen Hak Digital (DRM) dapat berjalan pada inti prosesor aplikasi yang sama seperti yang digunakan untuk kernel sistem operasi utama dan kode aplikasi. Kapan pun operasi kernel keamanan aktif pada inti secara efektif merupakan penghentian pekerjaan biasa yang biasanya berjalan pada inti tersebut. Secara khusus, ini mungkin termasuk pekerjaan audio. Berdasarkan sifatnya, perilaku internal kernel keamanan tidak dapat dipahami dari lapisan tingkat yang lebih tinggi, dan dengan demikian setiap anomali kinerja yang disebabkan oleh kernel keamanan sangatlah berbahaya. Misalnya, operasi kernel keamanan biasanya tidak muncul dalam jejak peralihan konteks. Kami menyebutnya "waktu gelap" — waktu yang telah berlalu namun tidak dapat diamati. Kernel keamanan harus dirancang untuk penghentian pekerjaan dalam kasus terburuk yang dapat diterima saat audio aktif.