Kontributor latensi audio

Halaman ini berfokus pada kontributor latensi output, tetapi diskusi serupa berlaku untuk latensi input.

Dengan asumsi bahwa sirkuit analog tidak berkontribusi secara signifikan, maka kontributor utama tingkat platform untuk latensi audio adalah sebagai berikut:

  • Permohonan
  • Jumlah total buffering dalam pipeline
  • Ukuran setiap buffer, dalam frame
  • Latensi tambahan setelah pemroses aplikasi, seperti dari DSP

Meskipun akurat, daftar kontributor di atas juga menyesatkan. Alasannya adalah jumlah buffer dan ukuran buffer lebih merupakan efek daripada penyebab. Yang biasanya terjadi adalah skema buffering tertentu diterapkan dan diuji, tetapi selama pengujian, audio yang kekurangan atau kelebihan buffer akan terdengar sebagai "klik" atau "pop". Untuk mengimbanginya, desainer sistem kemudian meningkatkan ukuran buffer atau jumlah buffer. Hal ini memiliki hasil yang diinginkan untuk menghilangkan underrun atau overrun, tetapi juga memiliki efek samping yang tidak diinginkan untuk meningkatkan latensi. Untuk mengetahui informasi selengkapnya tentang ukuran buffer, lihat video Latensi audio: ukuran buffer.

Pendekatan yang lebih baik adalah dengan memahami penyebab underrun dan overrun, lalu memperbaikinya. Hal ini akan menghilangkan artefak yang dapat didengar dan dapat memungkinkan buffering yang lebih kecil atau lebih sedikit sehingga mengurangi latensi.

Berdasarkan pengalaman kami, penyebab paling umum terjadinya underrun dan overrun meliputi:

  • CFS Linux (Completely Fair Scheduler)
  • thread prioritas tinggi dengan penjadwalan SCHED_FIFO
  • inversi prioritas
  • latensi penjadwalan yang lama
  • pengendali interupsi yang berjalan lama
  • waktu penonaktifan interupsi yang lama
  • pengelolaan daya
  • kernel keamanan

Penjadwalan CFS dan SCHED_FIFO Linux

CFS Linux dirancang agar adil bagi beban kerja yang bersaing yang berbagi resource CPU yang sama. Keadilan ini diwakili oleh parameter nice per thread. Nilai nice berkisar dari -19 (paling tidak bagus, atau paling banyak waktu CPU dialokasikan) hingga 20 (paling bagus, atau paling sedikit waktu CPU dialokasikan). 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 hanya "adil" selama periode pengamatan yang relatif lama. Selama periode pengamatan jangka pendek, CFS dapat mengalokasikan resource CPU dengan cara yang tidak terduga. Misalnya, ini dapat mengambil CPU dari thread dengan niceness numerik rendah ke thread dengan niceness numerik tinggi. Dalam kasus audio, hal ini dapat menyebabkan underrun atau overrun.

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

Prioritas SCHED_FIFO

Meskipun thread audio berperforma tinggi kini menggunakan SCHED_FIFO, thread tersebut masih rentan terhadap thread SCHED_FIFO prioritas tinggi lainnya. Thread 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 dengan prioritas 2 atau 3. Hal ini membuat prioritas 1 tersedia untuk thread prioritas lebih rendah, dan prioritas 4 hingga 99 untuk thread prioritas lebih tinggi. Sebaiknya gunakan prioritas 1 jika memungkinkan, dan siapkan prioritas 4 hingga 99 untuk thread yang dijamin akan selesai dalam jangka waktu yang terbatas, dijalankan dengan periode yang lebih singkat dari periode thread audio, dan diketahui tidak mengganggu penjadwalan thread audio.

Penjadwalan rate-monotonic

Untuk informasi selengkapnya tentang teori penetapan prioritas tetap, lihat artikel Wikipedia Penjadwalan rate-monotonic (RMS). Poin utamanya adalah prioritas tetap harus dialokasikan secara ketat berdasarkan periode, dengan prioritas yang lebih tinggi ditetapkan ke thread dengan periode yang lebih singkat, bukan berdasarkan "pentingnya" yang dirasakan. 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 dijalankan dengan frekuensi tak terbatas atau komputasi tak terbatas per eksekusi), thread tersebut tidak boleh diberi prioritas tetap karena tidak kompatibel dengan penjadwalan thread periodik yang sebenarnya.

Inversi prioritas

Inversi prioritas adalah mode kegagalan klasik sistem real-time, dengan tugas prioritas lebih tinggi diblokir untuk waktu yang tidak terbatas menunggu tugas prioritas lebih rendah melepaskan resource seperti (status bersama yang dilindungi oleh) mutex. Lihat artikel "Menghindari inversi prioritas" untuk mengetahui teknik untuk menguranginya.

Latensi penjadwalan

Latensi penjadwalan adalah waktu antara saat thread menjadi siap dijalankan dan saat pengalihan konteks yang dihasilkan selesai sehingga thread benar-benar berjalan di CPU. Makin pendek latensi, makin baik, dan apa pun yang lebih dari dua milidetik akan menyebabkan masalah pada audio. Latensi penjadwalan yang lama kemungkinan besar terjadi selama transisi mode, seperti mengaktifkan atau menonaktifkan CPU, beralih antara kernel keamanan dan kernel normal, beralih dari mode daya penuh ke mode daya rendah, atau menyesuaikan frekuensi dan voltase clock CPU.

Gangguan

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

Demikian pula, menonaktifkan interupsi di CPU 0 untuk waktu yang lama memiliki hasil yang sama dengan menunda pelayanan interupsi audio. Waktu penonaktifan interupsi yang lama biasanya terjadi saat menunggu spin lock kernel. Tinjau spin lock ini untuk memastikannya dibatasi.

Manajemen daya, performa, dan termal

Manajemen daya adalah istilah luas yang mencakup upaya untuk memantau dan mengurangi konsumsi daya sekaligus mengoptimalkan performa. Pengelolaan termal dan pendinginan komputer serupa, tetapi bertujuan untuk mengukur dan mengontrol panas guna menghindari kerusakan akibat panas berlebih. Dalam kernel Linux, pengelola CPU bertanggung jawab atas kebijakan tingkat rendah, sedangkan mode pengguna mengonfigurasi kebijakan tingkat tinggi. Teknik yang digunakan meliputi:

  • penskalaan tegangan dinamis
  • penskalaan frekuensi dinamis
  • pengaktifan core dinamis
  • pengalihan cluster
  • gating daya
  • hotplug (hotswap)
  • berbagai mode tidur (berhenti, berhenti, tidak ada aktivitas, ditangguhkan, dll.)
  • migrasi proses
  • afinitas prosesor

Beberapa operasi pengelolaan dapat menyebabkan "penghentian pekerjaan" atau waktu saat tidak ada pekerjaan yang berguna yang dilakukan oleh pemroses aplikasi. Penghentian pekerjaan ini dapat mengganggu audio, sehingga pengelolaan tersebut harus dirancang untuk penghentian pekerjaan terburuk yang dapat diterima saat audio aktif. Tentu saja, saat runaway termal akan segera terjadi, menghindari kerusakan permanen lebih penting daripada audio.

Kernel keamanan

Kernel keamanan untuk Pengelolaan hak digital (DRM) dapat berjalan di core prosesor aplikasi yang sama dengan yang digunakan untuk kernel sistem operasi utama dan kode aplikasi. Setiap kali operasi kernel keamanan aktif di core, secara efektif pekerjaan biasa yang biasanya berjalan di core tersebut akan dihentikan. Secara khusus, hal ini dapat mencakup karya audio. Secara alami, perilaku internal kernel keamanan tidak dapat dipahami dari lapisan tingkat yang lebih tinggi, sehingga anomali performa yang disebabkan oleh kernel keamanan sangat berbahaya. Misalnya, operasi kernel keamanan biasanya tidak muncul dalam rekaman aktivitas pengalihan konteks. Kami menyebutnya "waktu gelap" — waktu yang berlalu tetapi belum dapat diamati. Kernel keamanan harus dirancang untuk penghentian kerja kasus terburuk yang dapat diterima saat audio aktif.