本文件旨在提供良好和不良做法的總覽,協助您瞭解在 Fuchsia 中編寫新驅動程式或與現有驅動程式互動的效能。
本文件涵蓋下列主題:
API 定義
為新的驅動程式庫堆疊編寫 API 時,應考量一些關鍵效能深入分析資訊。驅動程式堆疊 API 屬於應用程式或驅動程式庫類別。
應用程式 API 可用來讓一般非驅動程式庫元件存取硬體資源,驅動程式庫 API 則用於讓驅動程式自行通訊。舉例來說,fuchsia.hardware.network
是可用來與網路驅動程式互動的應用程式 API,fuchsia.hardware.network.driver
則會定義網路裝置的較低層級驅動程式庫程式 API。
裝置驅動程式庫 API 通常是 fuchsia.hardware.*
banjo 和 fuchsia.hardware.*
FIDL API。
避免同步處理作業
屬於快速路徑的工作單位應該避免同步完成的預期,尤其是在作業需要跨越程序邊界的情況下,更應避免 (但不只是) 預期的情況。就 FIDL API 而言,設計時,如果到最後一個工作單元無法啟動,則在安全要求下一個工作單元之前,可能會產生不必要的同步處理,這表示呼叫端必須在安全的情況下要求下一個工作單元。
在緩慢路徑作業 (例如設定、拆解和設定) 中,效能觀點可以接受同步作業。
鼓勵批次處理
當 API 定義明確定義了批次作業,而不是一律傳輸單一單位時,API 使用者應透過其應用程式或驅動程式來擴增批次作業。
批次處理的重要功能,是減少一組工作內需要運動 API 的次數。如果 API 跨越程序邊界,直接轉譯為減少系統呼叫和排程負擔,有助於提高效能。
此外,如果 API 定義本身是提供批次工作單元,裝置驅動程式就可透過硬體加速功能,更輕鬆地將一組工作項目整理成單一單元。許多裝置驅動程式會使用 DMA,例如將工作與驅動的特定硬體排入佇列。如果一次收到一批工作項目,或許可以減少硬體的交易數量。如果沒有妥善的批次界限,裝置驅動程式就會強迫裝置驅動程式與硬體互動的頻率多於所需,或採用經驗法則 (例如輪詢間隔) 來減輕硬體通訊的負擔。
避免複製資料
在高頻寬或低延遲的應用程式 (例如網路、音訊或影片) 中,避免資料複製非常重要。大型酬載應盡可能在 VMO 中跨越 API 邊界。常見的策略是在作業期間,在設定和交換這些 VMO 區域時,交涉有限數量的 VMO。
清楚說明流量控制
如果 API 批次工作可正常運作,且未按照上述方式設定嚴格的同步作業,那麼控管 API 伺服器和用戶端之間的資訊流動過程,對於正確性和效能至關重要。
在一般作業中,API 的流程控制定義必須允許所有部分都能執行作業,而無需等待其等待,方法是確保系統能夠執行的工作總量維持不變 (以定義固定,或在設定時預先議定)。
舉例來說,在設定期間,fuchsia.hardware.network
會定義有限數量的「工作單位」(即網路封包),藉此強制執行流量控管。雙方隨時都知道有多少封包還是可以透過僅使用本機維護狀態,在 API 邊界上推送。
訂購帳戶
在某些應用程式中,所有工作單元都必須按照既定順序執行,以確保正確性。然而,在其他應用程式中,部分排序限制可能會完全削弱或解除。
如果工作項目串流不必按照確切順序執行,API 可以反映這一點,讓驅動程式和應用程式輕鬆識別可平行處理的工作。
舉例來說,網路封包通常必須維持順序,以免破壞應用程式通訊協定,但通常只有每個應用程式串流執行個體才適用此原則 (稱為「流程」)。網路轉接器中的常見策略是定義一組封包佇列,並透過確定性的方式將每個應用程式「流程」指派給其中一個佇列。網路堆疊即可安全地平行作業佇列,而不需查看封包的內容。觀察這類常見的硬體設施並在 API 中充分運用這些功能,就能打造出實際的效能改善措施。
實作
本節列出在實作提供或使用裝置驅動程式庫程式 API 的程式碼時,可觀察的效能模式和反模式。實作可以是驅動程式庫本身,也可以是與裝置驅動程式所提供服務互動的應用程式。
編寫快速路徑的程式碼時,應一律觀察到以下內容。請注意,就裝置驅動程式庫實作而言,快速路徑的一部分經常在中斷執行緒中運作。
- 避免分配記憶體或建立 Zircon 物件。在快速路徑上使用的資源一律應預先分配。使用可能引發隱性配置的 FIDL 繫結 (特別是 hlcpp) 或
fit::function
等程式庫時,請特別小心。 - 留意系統呼叫事件。Syscall 的作業成本可能高昂,因此,請小心不要在攸關效能的作業中呼叫核心。可能無法完全消除系統呼叫,但減少每個工作單元 (例如批次處理) 的呼叫次數可能會大幅降低系統負載。
- 快速傳回共用資源。如果 API 定義了有限的共用資源集區 (例如共用記憶體區域),您應盡可能重複使用這些資源或傳回到「可用」集區 (最好是批次處理)。
- 盡可能將 VMO 對應至唯讀,而非讀寫。將 VMO 對應為唯讀,可以減少《數位市場法》需要執行的快取作業數量。舉例來說,使用 DMA 寫入可能包含快取行的共用 VMO 時,快取必須在 DMA 前後清除並失效。另一方面,透過唯讀對應方式對應快取行已知會永遠乾淨,這表示只有在 DMA 完成後,才會將其清除並失效。