網路驅動程式中的效能
- 將傳送和接收路徑長度降至最低
- 分割資料和程式碼,以將跨處理器共用降到最低
- 避免誤分享
- 正確使用鎖定機制
- 使用 64 位 DMA
- 確保適當的緩衝區對齊
- 使用 Scatter-Gather DMA
- 支援接收端節流
將傳送和接收路徑長度降至最低
雖然傳送和接收路徑與驅動程式不同,但效能優化有一些一般規則:
針對通用路徑進行優化。 Kernprof.exe工具會提供給 Windows 的開發人員和 IDW 組建,以擷取所需的資訊。 開發人員應該查看耗用最多 CPU 週期的常式,並嘗試減少呼叫這些常式的頻率,或在這些常式中花費的時間。
縮短在 DPC 中花費的時間,讓網路介面卡驅動程式不會使用過多的系統資源,這會導致整體系統效能受到影響。
請確定偵錯程式碼未編譯成驅動程式的最終發行版本本;這可避免執行多餘的程式碼。
分割資料和程式碼,以將跨處理器共用降到最低
需要資料分割,才能將跨處理器的共用資料和程式碼降到最低。 資料分割有助於降低系統匯流排使用率,並改善處理器快取的有效性。 若要將共用降到最低,驅動程式寫入器應該考慮下列事項:
將驅動程式實作為還原序列化的迷你埠,如 還原序列化 NDIS 迷你埠驅動程式中所述。
使用每個處理器的資料結構來減少全域和共用資料存取。 這可讓您在不同步處理的情況下保留統計資料計數器,以減少程式碼路徑長度並增加效能。 對於重要統計資料,請在查詢時間將每個處理器計數器加在一起。 如果您必須具有全域計數器,請使用相互鎖定作業,而不是微調鎖定來操作計數器。 如需如何避免使用微調鎖定的資訊,請參閱下方正確使用鎖定機制。
為了協助達成此目標, KeGetCurrentProcessorNumberEx 可用來判斷目前的處理器。 若要判斷配置個別處理器資料結構時的處理器數目,可以使用 KeQueryGroupAffinity 。
affinity mask 中設定的位總數表示系統中的作用中處理器數目。 驅動程式不應該假設遮罩中的所有設定位都會連續,因為處理器可能不會在未來的作業系統版本中連續編號。 SMP 機器中的處理器數目是以零起始的值。
如果您的驅動程式維護每個處理器的資料,您可以使用 KeQueryGroupAffinity 函式來減少快取行競爭。
避免誤分享
當處理器要求彼此獨立的共用變數時,就會發生 False 共用。 不過,由於變數位於相同的快取行上,因此它們會在處理器之間共用。 在這種情況下,快取行會在處理器之間來回移動,以便每次存取其中任何變數,導致快取排清和重載增加。 這會增加系統匯流排使用率,並減少整體系統效能。
若要避免誤共用,請使用 NdisGetSharedDataAlignment將重要的資料結構對齊 (,例如微調鎖定、緩衝區佇列標頭、) 連結清單。
正確使用鎖定機制
如果未正確使用,微調鎖定可能會降低效能。 驅動程式應該盡可能使用相互鎖定作業,將微調鎖定的使用降到最低。 不過,在某些情況下,微調鎖定可能是某些用途的最佳選擇。 例如,如果驅動程式在處理尚未向驅動程式指出的封包數目時取得微調鎖定,就不需要使用連結作業。 如需詳細資訊,請參閱 網路驅動程式中的同步處理和通知。
以下是有效使用鎖定機制的一些秘訣:
使用 NDIS 單一連結清單函式,例如下列來管理資源集區:
如果您需要使用微調鎖定,請使用它們只保護資料,而不是程式碼。 請勿使用一個鎖定來保護常見路徑中使用的所有資料。 例如,將傳送和接收路徑中使用的資料分成兩個資料結構,以便在傳送路徑需要鎖定其資料時,接收路徑不會受到影響。
如果您使用微調鎖定,且路徑已經在 DPC 層級,請使用 NdisDprAcquireSpinLock 和 NdisDprReleaseSpinLock 函式,以避免取得和釋放鎖定時的額外程式碼。
若要將微調鎖定取得和釋放的數目降到最低,請使用下列 NDIS RWLock 函式:
使用 64 位 DMA
64 位 DMA 如果網路介面卡支援 64 位 DMA,則必須採取步驟,以避免超過 4 GB 範圍之位址的額外複本。 當驅動程式呼叫NdisMRegisterScatterGatherDma時,必須在Flags參數中設定NDIS_SG_DMA_64_BIT_ADDRESS旗標。
確保適當的緩衝區對齊
快取行界限上的緩衝區對齊可改善將資料從一個緩衝區複製到另一個緩衝區時的效能。 大部分的網路介面卡接收緩衝區會在第一次配置時正確對齊,但最終必須複製到應用程式緩衝區的使用者資料因為耗用標頭空間而不正確。 在 TCP 資料 (最常見的案例) ,由於 TCP、IP 和乙太網路標頭而造成的轉移會導致0x36位元組移位。 若要解決此問題,建議驅動程式配置稍微較大的緩衝區,並將封包資料插入位移0xA位元組。 這可確保在緩衝區移位之後,0x36個標頭的位元組,使用者資料會正確對齊。 如需快取行界限的詳細資訊,請參閱 NdisMAllocateSharedMemory的一節。
使用 Scatter-Gather DMA
NDIS 散佈/收集 DMA 提供硬體支援,以在非連續的實體記憶體範圍內來回傳輸資料。 Scatter-Gather DMA 使用 SCATTER_GATHER_LIST 結構,其中包括 SCATTER_GATHER_ELEMENT 結構的陣列,以及陣列中的元素數目。 此結構是從傳遞至驅動程式傳送函式的封包描述項擷取。 陣列的每個元素都會提供實體連續Scatter-Gather區域的長度和起始實體位址。 驅動程式會使用長度和位址資訊來傳輸資料。
使用 DMA 作業的Scatter-Gather常式,可以藉由不以靜態方式鎖定這些資源來改善系統資源的使用率,就像使用地圖暫存器時一樣。 如需詳細資訊,請參閱 NDIS 散佈/收集 DMA。
如果網路介面卡支援 TCP 分割卸載 (大型傳送卸載) ,驅動程式就必須將它可從 TCP/IP 取得的最大緩衝區大小傳入NdisMRegisterScatterGatherDma函式內的MaximumPhysicalMapping參數。 這可確保驅動程式有足夠的對應暫存器來建置Scatter-Gather清單,並消除任何可能的緩衝區配置和複製。 如需詳細資訊,請參閱下列主題:
支援接收端節流
若要將多媒體應用程式中媒體播放期間的中斷降到最低,NDIS 6.20 和更新版本的驅動程式必須支援接收端節流 (RST) 處理接收中斷。 如需詳細資訊,請參閱
NDIS 6.20 中的接收端節流將Miniport 驅動程式移植到 NDIS 6.20 所需的變更摘要中的「傳送和接收程式碼路徑」