共用方式為


WavePci Miniport 驅動程式的效能問題

您可以遵循下列一般原則,大幅降低音訊驅動程式對系統的效能影響:

  • 將正常作業期間執行的程式碼降到最低。

  • 僅在必要時執行程式碼。

  • 請考慮 (系統資源耗用量總計,而不只是 CPU 載入) 。

  • 優化程式碼的速度和大小。

此外,WavePci 迷你埠驅動程式必須解決音訊裝置特有的數個效能問題。 下列討論主要處理音訊轉譯問題,雖然某些建議的技術也適用于音訊擷取。

串流服務機制

在討論效能優化之前,必須有一些背景,才能瞭解維護資料流程的 WavePci 機制。

處理波轉譯或擷取串流時,音訊裝置需要定期由迷你埠驅動程式提供服務。 當資料流程有新的對應可用時,驅動程式會將這些對應新增至資料流程的 DMA 佇列。 驅動程式也會從佇列中移除任何已經處理的對應。 如需對應的相關資訊,請參閱 WavePci 延遲

若要執行服務,迷你埠驅動程式會根據系統計時器或 DMA 驅動中斷中斷,提供 延遲程序呼叫 (DPC) 或插斷服務常式 (ISR) 。 在後者的情況下,DMA 硬體通常會在每次完成傳輸某些資料流程資料時觸發中斷。

每次執行 DPC 或 ISR 時,都會判斷哪些資料流程需要服務。 DPC 或 ISR 會藉由呼叫 IPortWavePci::Notify 方法來服務資料流程。 這個方法會採用資料流程服務群組的呼叫參數,這是 IServiceGroup類型的物件。 Notify方法會呼叫服務群組的RequestService方法 (請參閱IServiceSink::RequestService) 。

service-group 物件包含一組服務接收,也就是 IServiceSink類型的物件。 IServiceGroup 衍生自 IServiceSink ,而且兩個介面都有 RequestService 方法。 當 Notify 方法呼叫服務群組的 RequestService 方法時,服務群組會在群組中的每個服務接收上呼叫 RequestService 方法來回應。

資料流程的服務群組至少包含一個服務接收,埠驅動程式會在建立資料流程之後立即新增至服務群組。 埠驅動程式會呼叫迷你埠驅動程式的 IMiniportWavePci::NewStream 方法,以取得服務群組的指標。 服務接收的 RequestService 方法是埠驅動程式的資料流程特定服務常式。 此常式會執行下列動作:

  • 呼叫迷你埠驅動程式的 IMiniportWavePciStream::Service 方法。

  • 在上次執行服務常式之後,觸發資料流程上任何新擱置中的位置或時鐘事件。

KS 事件中所述,當資料流程到達特定位置或時鐘到達特定時間戳記時,用戶端可以註冊以收到通知。 NewStream方法可以選擇不提供服務群組,在此情況下,埠驅動程式會設定自己的計時器,以標示呼叫其服務常式之間的間隔。

如同 NewStream 方法,迷你埠驅動程式的 IMiniportWavePci::Init 方法也會輸出服務群組的指標。 在 Init 呼叫之後,埠驅動程式會將其服務接收新增至服務群組。 這個特定的服務接收包含整個篩選的服務常式。 (上一個段落描述與 filter.) 此服務常式會呼叫迷你埠驅動程式的 IMiniportWavePci::Service 方法上與針腳相關聯的資料流程服務接收。 每次使用篩選的服務群組呼叫 Notify 時,服務常式就會執行。 Init方法可以選擇不提供服務群組,在此情況下,埠驅動程式永遠不會呼叫其篩選服務常式。

硬體中斷

某些迷你埠驅動程式會產生太多或沒有足夠的硬體中斷。 在某些具有 DirectSound 硬體加速的 WavePci 轉譯裝置中,只有在提供對應幾乎耗盡且轉譯引擎有耗盡的風險時,才會發生硬體中斷。 在其他硬體加速的 WavePci 裝置中,每一個對應完成或一些相對較小的間隔都會發生硬體中斷。 在此情況下,ISR 經常發現它幾乎不需要這麼做,但每個中斷仍會耗用具有暫存器交換和快取重載的系統資源。 改善驅動程式效能的第一個步驟是盡可能減少中斷次數,而不會造成耗盡的風險。 消除不必要的中斷之後,藉由設計 ISR 以更有效率地執行,即可達成額外的效能提升。

在某些驅動程式中,ISR 會在每次發生硬體中斷時呼叫資料流程的 Notify 方法來浪費時間,而不論資料流程是否實際執行。 如果沒有任何資料流程處於 RUN 狀態,則 DMA 處於非作用中狀態,而且任何嘗試取得對應、釋放對應或檢查任何資料流程中是否有新事件所花費的時間都會浪費。 在有效率的驅動程式中,ISR 會先確認資料流程正在執行,然後再呼叫資料流程的 Notify 方法。

不過,具有這種 ISR 類型的驅動程式必須確定當資料流程結束 RUN 狀態時,會觸發資料流程上的任何暫止事件。 否則,事件可能會延遲或遺失。 只有在比 Microsoft Windows XP 還舊的作業系統執行到 PAUSE 轉換期間,才會發生此問題。 在 Windows XP 和更新版本中,當資料流程將狀態從 RUN 變更為 PAUSE 時,埠驅動程式會自動發出任何未處理的位置事件訊號。 不過,在較舊的作業系統中,迷你埠驅動程式會負責觸發任何未處理的事件,方法是在串流暫停後立即呼叫 Notify 。 如需詳細資訊,請參閱下面的 PAUSE/ACQUIRE 優化。

典型的 WavePci 迷你埠驅動程式會從 KMixer 系統驅動程式管理單一播放串流。 KMixer 目前的實作會使用至少三個對應 IRP 來緩衝播放資料流程。 每個 IRP 都包含足夠的緩衝區儲存體,大約 10 毫秒的音訊。 如果迷你埠驅動程式會在每次 DMA 控制器完成 IRP 中的最終對應時觸發硬體中斷,則中斷應該以相當一般的 10 毫秒間隔發生,這很頻繁,足以讓 DMA 佇列免于耗盡。

計時器 DPC

如果驅動程式管理任何硬體加速 DirectSound 資料流程,它應該使用計時器 DPC (請參閱 計時器物件和 DPC) ,而不是 DMA 驅動硬體中斷。 同樣地,具有內建計時器之 PCI 記憶卡上的 WavePci 裝置可以使用計時器驅動硬體中斷,而不是 DPC。

在 DirectSound 緩衝區的情況下,整個緩衝區可以附加至單一 IRP。 如果緩衝區很大,而迷你埠驅動程式只會在到達緩衝區結尾時排程硬體中斷,則連續中斷會到目前為止發生,而 DMA 佇列會耗盡。 此外,如果驅動程式正在管理大量的硬體加速 DirectSound 資料流程,而且每個資料流程都會產生自己的中斷,則所有中斷的累積影響可能會降低系統效能。 在這些情況下,迷你埠驅動程式應該避免使用硬體中斷來排程個別資料流程的服務。 相反地,它應該在排定在一般計時器產生的間隔執行的單一 DPC 中服務所有資料流程。

藉由將計時器間隔設定為 10 毫秒,後續 DPC 執行之間的間隔類似于先前在單一 KMixer 播放資料流程中針對硬體中斷所描述的間隔。 因此,除了硬體加速的 DirectSound 串流之外,DPC 還可以處理 KMixer 播放串流。

當最後一個資料流程結束 RUN 狀態時,迷你埠驅動程式應該停用計時器 DPC,以避免系統 CPU 週期浪費。 在停用 DPC 之後,驅動程式應該確定先前執行之資料流程上擱置的任何時鐘或位置事件都會排清。 在 Windows 98/Me 和 Windows 2000 中,驅動程式應該呼叫 Notify 來觸發正在暫停之資料流程上的任何擱置事件。 在 Windows XP 和更新版本中,當資料流程結束 RUN 狀態時,作業系統會自動觸發任何擱置的事件,而不需要迷你埠驅動程式介入。

PAUSE/ACQUIRE 優化

在 Windows 98/Me 和 Windows 2000 中,WavePci 埠驅動程式的串流服務常式 (RequestService 方法) 一律會產生迷你埠驅動程式 IMiniportWavePciStream::Service 方法的呼叫,而不論資料流程是否處於 RUN 狀態。 在這些作業系統中, Service 方法應該先檢查資料流程是否正在執行,然後再花費時間執行實際工作。 不過, (,如果迷你埠驅動程式的 DPC 或 ISR 已優化,只針對正在執行的資料流程呼叫 Notify ,請將這項檢查新增至 Service 方法可能是多餘的。)

在 Windows XP 和更新版本中,這項優化是不必要的,因為 Notify 方法只會在執行的資料流程上呼叫 Service 方法。

使用 IPreFetchOffset 介面

DirectSound 使用者熟悉播放游標和寫入游標的雙重概念。 播放游標會指出從裝置發出之資料流程中的位置, (驅動程式目前在 DAC) 的最佳樣本估計值。 寫入位置是用戶端寫入其他資料之下一個安全位置資料流程中的位置。 對於 WavePci,預設假設是寫入資料指標位於所要求的最後一個對應結尾。 如果迷你埠驅動程式已取得大量的未處理對應,播放游標和寫入游標之間的位移可能非常大,足以讓某些 WHQL 音訊位置測試失敗。 在 Windows XP 和更新版本中, IPreFetchOffset 介面可解決這些問題。

迷你埠驅動程式會使用 IPreFetchOffset 來指定匯流排主機硬體的預先擷取特性,主要取決於硬體 FIFO 大小。 音訊子系統會使用此資料來設定播放游標與寫入游標之間的常數位移。 這個常數位移可以明顯小於預設位移,利用資料可以寫入對應的事實,即使將對應交給硬體之後,只要播放資料指標遠于寫入資料的位置即可。 (此語句假設驅動程式不會複製或操作 mappings 中的資料。) 一般位移可能會依引擎設計的順序 64 個樣本而定。 有了這個小的位移,WavePci 驅動程式可以完全回應且可正常運作,同時仍要求大量的對應。

請注意,DirectSound 目前會填補硬體加速針腳的寫入游標 10 毫秒。

如需詳細資訊,請參閱 預先擷取位移

處理對應中的資料

請盡可能避免硬體驅動程式觸碰對應中的資料。 對應中包含的任何軟體處理應該分割成與硬體驅動程式不同的軟體篩選器。 讓硬體驅動程式執行這類處理可降低其效率,並產生延遲問題。

硬體驅動程式應該致力於透明地瞭解其實際硬體功能。 驅動程式絕對不應該宣告為實際在軟體中執行的資料轉換提供硬體支援。

同步處理基本類型

現在,如果驅動程式的程式碼設計為避免盡可能遭到封鎖,則驅動程式不太可能發生死結或效能問題。 具體而言,驅動程式的執行執行緒應該致力於執行到完成,而不需要等待另一個執行緒或資源時停止的風險。 例如,驅動程式執行緒可以使用 InterlockedXxx 函式 (,例如 ,請參閱 InterlockedIncrement) 協調對特定共用資源的存取,而不會有遭到封鎖的風險。

雖然這些是功能強大的技術,但您可能無法安全地從執行路徑移除所有微調鎖定、Mutex 和其他封鎖同步處理基本類型。 使用 InterlockedXxx 函式,並瞭解無限等候可能會導致資料耗盡。

最重要的是,請勿建立自訂同步處理基本類型。 內建的 Windows 基本類型 (mutex、微調鎖定等) 可能會視需要修改以支援未來的新排程器功能,而且使用自訂建構的驅動程式幾乎保證不會在未來運作。

IPinCount 介面

在 Windows XP 和更新版本中, IPinCount 介面提供一種方式,讓迷你埠驅動程式更精確地考慮配置針腳所耗用的硬體資源。 藉由呼叫 miniport 驅動程式的 IPinCount::P inCount 方法,埠驅動程式會執行下列動作:

  • 將篩選的目前針腳計數公開 (,如埠驅動程式) 至迷你埠驅動程式所維護。

  • 讓迷你埠驅動程式有機會修改針腳計數,以動態反映硬體資源的目前可用性。

對於某些音訊裝置,具有不同屬性的波浪串流 (3D、立體/單聲道等等,) 在取用的硬體資源數量方面也可能有不同的「權數」。 開啟或關閉「輕量型」資料流程時,驅動程式會遞增或遞減可用針腳的計數。 不過,開啟「重載」資料流程時,迷你埠驅動程式可能需要將可用的針腳計數減去兩個,而不是一個,以便更精確地指出可以使用其餘資源建立的針腳數目。

關閉粗量資料流程時,會反轉此程式。 可用的針腳計數可能會增加一個以上,以反映可以從新釋放的資源建立兩個或多個輕量型資料流程的事實。