本頁重點介紹導致輸出延遲的因素,但類似的討論也適用於輸入延遲。
假設模擬電路沒有顯著貢獻,那麼音頻延遲的主要表面級貢獻者如下:
- 應用
- 管道中的緩衝區總數
- 每個緩衝區的大小,以幀為單位
- 應用處理器之後的額外延遲,例如來自 DSP
儘管上述貢獻者列表可能很準確,但它也具有誤導性。原因是緩衝區計數和緩衝區大小更多的是影響而不是原因。通常發生的情況是實現並測試了給定的緩衝區方案,但在測試期間,音頻欠載或溢出被聽到為“咔噠”或“爆音”。作為補償,系統設計人員隨後會增加緩衝區大小或緩衝區計數。這具有消除欠載或超載的理想結果,但它也具有增加延遲的不良副作用。有關緩衝區大小的更多信息,請參閱視頻音頻延遲:緩衝區大小。
更好的方法是了解欠載和超載的原因,然後進行糾正。這消除了可聽見的偽影,並可能允許更小或更少的緩衝區,從而減少延遲。
根據我們的經驗,欠載和超支的最常見原因包括:
- Linux CFS(完全公平調度器)
- 具有 SCHED_FIFO 調度的高優先級線程
- 優先級倒置
- 長調度延遲
- 長時間運行的中斷處理程序
- 長中斷禁用時間
- 能源管理
- 安全內核
Linux CFS 和 SCHED_FIFO 調度
Linux CFS 旨在對共享公共 CPU 資源的競爭工作負載公平。這種公平性由每個線程的 nice參數表示。 nice 值的範圍從 -19(分配的最少或最多的 CPU 時間)到 20(分配的最佳或最少的 CPU 時間)。通常,具有給定 nice 值的所有線程接收大約相等的 CPU 時間,而具有數值較低 nice 值的線程應該期望接收更多 CPU 時間。然而,CFS 僅在相對較長的觀察期內是“公平的”。在短期觀察窗口中,CFS 可能會以意想不到的方式分配 CPU 資源。例如,它可能會將 CPU 從一個數值較低的線程轉移到一個數值較高的線程上。在音頻的情況下,這可能導致欠載或溢出。
顯而易見的解決方案是為高性能音頻線程避免 CFS。從 Android 4.1 開始,此類線程現在使用SCHED_FIFO
調度策略,而不是 CFS 實現的SCHED_NORMAL
(也稱為SCHED_OTHER
)調度策略。
SCHED_FIFO 優先級
儘管高性能音頻線程現在使用SCHED_FIFO
,但它們仍然容易受到其他更高優先級SCHED_FIFO
線程的影響。這些通常是內核工作線程,但也可能有一些具有策略SCHED_FIFO
的非音頻用戶線程。可用的SCHED_FIFO
優先級範圍從 1 到 99。音頻線程以優先級 2 或 3 運行。這使得優先級 1 可用於較低優先級的線程,而優先級 4 到 99 可用於較高優先級的線程。我們建議您盡可能使用優先級 1,並為那些保證在有限時間內完成、執行週期短於音頻線程週期並且已知不會干擾調度的線程保留優先級 4 到 99的音頻線程。
速率單調調度
有關固定優先級分配理論的更多信息,請參閱維基百科文章速率單調調度(RMS)。一個關鍵點是,固定優先級應該嚴格根據周期分配,較高的優先級分配給周期較短的線程,而不是基於感知的“重要性”。非週期性線程可以建模為周期性線程,使用最大執行頻率和每次執行的最大計算量。如果非週期性線程不能被建模為周期性線程(例如,它可以以無限頻率或每次執行的無限計算執行),則不應為其分配固定優先級,因為這與真正週期性線程的調度不兼容.
優先級反轉
優先級反轉是實時系統的經典故障模式,其中較高優先級的任務被阻塞一段無限的時間,等待較低優先級的任務釋放資源,例如(受保護的共享狀態)互斥鎖。請參閱文章“避免優先級倒置”以了解緩解它的技術。
調度延遲
調度延遲是線程準備好運行和結果上下文切換完成之間的時間,以便線程實際在 CPU 上運行。延遲越短越好,任何超過兩毫秒的時間都會導致音頻出現問題。較長的調度延遲最有可能發生在模式轉換期間,例如啟動或關閉 CPU、在安全內核和普通內核之間切換、從全功率模式切換到低功率模式或調整 CPU 時鐘頻率和電壓.
中斷
在許多設計中,CPU 0 服務於所有外部中斷。因此,長時間運行的中斷處理程序可能會延遲其他中斷,尤其是音頻直接內存訪問 (DMA) 完成中斷。設計中斷處理程序以快速完成並將冗長的工作推遲到線程(最好是 CFS 線程或優先級為 1 的SCHED_FIFO
線程)。
等效地,長時間禁用 CPU 0 上的中斷與延遲音頻中斷服務的結果相同。長中斷禁用時間通常發生在等待內核自旋鎖時。檢查這些自旋鎖以確保它們是有界的。
電源、性能和熱管理
電源管理是一個廣義的術語,包括在優化性能的同時監控和降低功耗的努力。熱管理和計算機冷卻相似,但尋求測量和控制熱量以避免因過熱而損壞。在 Linux 內核中,CPU調控器負責低級策略,而用戶態配置高級策略。使用的技術包括:
- 動態電壓縮放
- 動態頻率縮放
- 動態核心啟用
- 集群交換
- 電源門控
- 熱插拔(熱插拔)
- 各種睡眠模式(暫停、停止、空閒、掛起等)
- 進程遷移
- 處理器親和性
一些管理操作可能導致“工作停止”或應用處理器沒有執行有用工作的時間。這些停工可能會干擾音頻,因此此類管理應設計為在音頻處於活動狀態時可接受的最壞情況下的停工。當然,當熱失控迫在眉睫時,避免永久性損壞比音頻更重要!
安全內核
用於數字版權管理(DRM) 的安全內核可以在與用於主操作系統內核和應用程序代碼的應用處理器內核相同的應用處理器內核上運行。安全內核操作在內核上處於活動狀態的任何時間實際上都是正常工作在該內核上運行的停止。特別是,這可能包括音頻作品。就其本質而言,安全內核的內部行為對於高層來說是難以捉摸的,因此由安全內核引起的任何性能異常都是特別有害的。例如,安全內核操作通常不會出現在上下文切換跟踪中。我們稱之為“黑暗時間”——已經過去但無法觀察到的時間。安全內核應設計為在音頻處於活動狀態時可接受的最壞情況下的停工。