Halaman ini berfokus pada kontributor latensi keluaran, tetapi diskusi serupa berlaku untuk latensi masukan.
Dengan asumsi sirkuit analog tidak berkontribusi secara signifikan, maka kontributor tingkat permukaan utama untuk latensi audio adalah sebagai berikut:
- Aplikasi
- Jumlah total buffer dalam pipa
- Ukuran setiap buffer, dalam bingkai
- Latensi tambahan setelah prosesor aplikasi, seperti dari DSP
Seakurat daftar kontributor di atas, itu juga menyesatkan. Alasannya adalah jumlah buffer dan ukuran buffer lebih merupakan efek daripada penyebab . Apa yang biasanya terjadi adalah skema buffer yang diberikan diimplementasikan dan diuji, tetapi selama pengujian, audio underrun atau overrun terdengar sebagai "klik" atau "pop". Untuk mengimbanginya, perancang sistem kemudian meningkatkan ukuran buffer atau jumlah buffer. Ini memiliki hasil yang diinginkan untuk menghilangkan underruns atau overruns, tetapi juga memiliki efek samping yang tidak diinginkan dari peningkatan latensi. Untuk informasi selengkapnya tentang ukuran buffer, lihat video Latensi audio: ukuran buffer .
Pendekatan yang lebih baik adalah memahami penyebab underruns dan overruns, dan kemudian memperbaikinya. Ini menghilangkan artefak yang dapat didengar dan memungkinkan buffer yang lebih kecil atau lebih sedikit dan dengan demikian mengurangi latensi.
Dalam pengalaman kami, penyebab paling umum dari underruns dan overruns meliputi:
- Linux CFS (Penjadwal Sepenuhnya Adil)
- utas prioritas tinggi dengan penjadwalan SCHED_FIFO
- inversi prioritas
- latensi penjadwalan yang panjang
- penangan interupsi yang berjalan lama
- waktu penonaktifan interupsi yang lama
- manajemen daya
- kernel keamanan
Penjadwalan Linux CFS dan SCHED_FIFO
CFS Linux dirancang agar adil terhadap beban kerja bersaing yang berbagi sumber daya CPU yang sama. Keadilan ini diwakili oleh parameter Nice per-utas. Nilai bagus berkisar dari -19 (paling tidak bagus, atau sebagian besar waktu CPU dialokasikan) hingga 20 (waktu CPU terbaik, atau paling sedikit dialokasikan). Secara umum, semua utas dengan nilai bagus yang diberikan menerima waktu CPU yang kira-kira sama dan utas dengan nilai bagus yang lebih rendah secara numerik akan menerima lebih banyak waktu CPU. Namun, CFS "adil" hanya selama periode pengamatan yang relatif lama. Selama jendela observasi jangka pendek, CFS dapat mengalokasikan sumber daya CPU dengan cara yang tidak terduga. Misalnya, mungkin mengambil CPU dari utas dengan niceness yang rendah secara numerik ke utas dengan niceness yang secara numerik tinggi. Dalam hal audio, ini dapat mengakibatkan underrun atau overrun.
Solusi yang jelas adalah menghindari CFS untuk utas audio berkinerja tinggi. Mulai Android 4.1, utas tersebut sekarang menggunakan kebijakan penjadwalan SCHED_FIFO
daripada kebijakan penjadwalan SCHED_NORMAL
(juga disebut SCHED_OTHER
) yang diterapkan oleh CFS.
Prioritas SCHED_FIFO
Meskipun utas audio berkinerja tinggi sekarang menggunakan SCHED_FIFO
, utas tersebut masih rentan terhadap utas SCHED_FIFO
berprioritas lebih tinggi lainnya. Ini biasanya utas pekerja kernel, tetapi mungkin juga ada beberapa utas pengguna non-audio dengan kebijakan SCHED_FIFO
. Prioritas SCHED_FIFO
tersedia berkisar dari 1 hingga 99. Utas audio berjalan pada prioritas 2 atau 3. Hal ini membuat prioritas 1 tersedia untuk utas dengan prioritas lebih rendah, dan prioritas 4 hingga 99 untuk utas dengan prioritas lebih tinggi. Kami menyarankan Anda menggunakan prioritas 1 bila memungkinkan, dan mencadangkan prioritas 4 hingga 99 untuk utas yang dijamin selesai dalam jumlah waktu yang dibatasi, mengeksekusi dengan periode yang lebih pendek dari periode utas audio, dan diketahui tidak mengganggu penjadwalan dari utas audio.
Penjadwalan tingkat-monoton
Untuk informasi lebih lanjut tentang teori penetapan prioritas tetap, lihat artikel Wikipedia Penjadwalan tingkat-monotonik (RMS). Poin kuncinya adalah bahwa prioritas tetap harus dialokasikan secara ketat berdasarkan periode, dengan prioritas yang lebih tinggi diberikan pada rangkaian periode yang lebih pendek, bukan berdasarkan persepsi "pentingnya". Utas non-periodik dapat dimodelkan sebagai utas periodik, menggunakan frekuensi eksekusi maksimum dan komputasi maksimum per eksekusi. Jika utas non-periodik tidak dapat dimodelkan sebagai utas periodik (misalnya ia dapat dieksekusi dengan frekuensi tak terbatas atau komputasi tak terbatas per eksekusi), maka ia tidak boleh diberi prioritas tetap karena hal itu tidak sesuai dengan penjadwalan utas periodik sejati. .
Pembalikan prioritas
Pembalikan prioritas adalah mode kegagalan klasik dari sistem waktu nyata, di mana tugas dengan prioritas lebih tinggi diblokir untuk waktu yang tidak terbatas menunggu tugas dengan prioritas lebih rendah untuk melepaskan sumber daya seperti (keadaan bersama yang dilindungi oleh) mutex . Lihat artikel " Menghindari inversi prioritas " untuk teknik untuk menguranginya.
Penjadwalan latensi
Latensi penjadwalan adalah waktu antara saat utas siap dijalankan dan saat sakelar konteks yang dihasilkan selesai sehingga utas benar-benar berjalan pada CPU. Semakin pendek latensi semakin baik, dan apa pun yang lebih dari dua milidetik menyebabkan masalah 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 tegangan clock CPU .
Interupsi
Dalam banyak desain, CPU 0 melayani semua interupsi eksternal. Jadi pengendali interupsi yang berjalan lama dapat menunda interupsi lain, khususnya interupsi penyelesaian akses memori langsung audio (DMA). Rancang penangan interupsi untuk menyelesaikan dengan cepat dan menunda pekerjaan yang lama ke utas (lebih disukai utas CFS atau utas SCHED_FIFO
dengan prioritas 1).
Sama halnya, menonaktifkan interupsi pada CPU 0 untuk waktu yang lama memiliki hasil yang sama dengan penundaan layanan interupsi audio. Waktu penonaktifan interupsi yang lama biasanya terjadi saat menunggu kunci putaran kernel . Tinjau kunci putar ini untuk memastikannya dibatasi.
Daya, kinerja, dan manajemen termal
Manajemen daya adalah istilah luas yang mencakup upaya untuk memantau dan mengurangi konsumsi daya sambil 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 antara lain:
- penskalaan tegangan dinamis
- penskalaan frekuensi dinamis
- inti dinamis memungkinkan
- perpindahan klaster
- gerbang listrik
- hotplug (hotswap)
- berbagai mode tidur (halt, stop, idle, suspend, dll.)
- proses migrasi
- afinitas prosesor
Beberapa operasi manajemen dapat mengakibatkan "penghentian kerja" atau waktu di mana tidak ada pekerjaan berguna yang dilakukan oleh prosesor aplikasi. Penghentian kerja ini dapat mengganggu audio, jadi manajemen tersebut harus dirancang untuk penghentian kerja 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. Setiap saat selama 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. Secara alami, perilaku internal kernel keamanan tidak dapat dipahami dari lapisan tingkat yang lebih tinggi, dan dengan demikian setiap anomali kinerja yang disebabkan oleh kernel keamanan sangat merusak. Misalnya, operasi kernel keamanan biasanya tidak muncul dalam pelacakan sakelar konteks. Kami menyebutnya "waktu gelap" — waktu yang berlalu namun tidak dapat diamati. Kernel keamanan harus dirancang untuk penghentian pekerjaan kasus terburuk yang dapat diterima saat audio aktif.