DPDK — 數據平臺優化技術

目錄

DPDK 優化技術

DPDK 優化技術指在 DPDK 應用過程中,爲進一步提高各類用戶應用程序的轉發性能,所採取的性能調優方法和關鍵配置。

DPDK 性能影響因素

本節主要介紹基於 DPDK 進行應用開發和環境配置時,應用程序性能的影響因素以及相應的優化調整方法。這些因素並非必然劣化性能,可能因硬件能力、OS 版本、各類軟硬環境參數配置等的差異產生較大波動,或者存在較大的不穩定性,相關的調優方法需要用戶結合自身的 VNF 應用部署在實踐中不斷完善。

硬件結構的影響

DPDK 具有廣泛的平臺適應性,可以運行在整個 x86 平臺,從主流服務器平臺(從高性能或者高能效產品系列),到桌面或者嵌入式平臺,也可以運行於基於 Power 或者其他架構的運算平臺。下圖展示了一個通用雙路服務器的內部架構,它包含了 2 箇中央處理器,2 個分離的內存控制單元來連接系統內存,芯片組會擴展出大量高速的 PCIe 2.0/3.0 接口,用於連接外設,如 10Gbps 或者 25Gbps 網卡外設。

在這裏插入圖片描述
硬件規格對 DPDK 性能的影響體現在幾個方面:

  • CPU 頻率:CPU 頻率越高,DPDK 性能越高。
  • LLC(Last Leve Cache)大小:緩存越大,DPDK 性能越高。
  • PCIe Lane 的數目:PCIe 鏈路可以支持 1、2、4、8、12、16 和 32 個 Lane,需要確保其帶寬可以滿足所插網卡的帶寬。
  • NUMA:網絡數據報文的處理由網卡所在的 NUMA 節點處理,將會比遠端 NUMA 節點處理的性能更高。

OS 版本及其內核的影響

不同的 Linux OS 發行版使用的 Linux 內核版本不一樣,配置的 Linux OS 服務也不一樣。這些差異都會導致應用程序在網絡報文處理能力上有所差別。由於 Linux 內核還在不斷演進,Linux 的發行版也數量衆多,同樣的硬件配置環境下,不同的 Linux 發行版在小包的處理能力上存在差異。本文無法提供最佳 Linux 內核版本和配置,而只能給出部分參考建議,如:關閉部分 OS 服務。

OVS 性能問題

OVS 作爲 NFV 的一個重要組成模塊,會運行在絕大多數的服務器節點上,提供虛擬機和虛擬機之間,以及虛擬網絡和物理網絡間的互連接口,其性能至關重要。OVS 2.4 開始正式支持 DPDK 加速,相比傳統基於 Linux 內核的 OVS 版本,轉發性能提高了數倍,爲 VNF 在通用 x86 服務器上部署提供了有力支持。

OVS 缺省會爲每一個 NUMA 節點創建一個 pmd 線程,該 pmd 線程以輪詢方式處理屬於其 NUMA 節點上的所有 DPDK 接口。爲了高性能,需要利用前面提到的 CPU 綁核技術,把 pmd 線程綁定在一個固定的 CPU core 上處理。此外,爲了增加擴展性,OVS 2.4 也支持網卡多隊列以及多 pmd 線程數,這些參數均可動態配置,但具體配置應根據具體需求來決定。

內存管理

如前所述,DPDK 考慮了 NUMA 以及多內存通道的訪問效率,會在系統運行前要求配置 Linux 的 HugePage,初始化時申請其內存池,用於 DPDK 運行的主要內存資源。Linux 大頁機制利用了處理器核上的的 TLB 的 HugePage 表項,這可以減少內存地址轉換的開銷。

CPU 核間無鎖通信

如果想建立一個基於消息傳遞的核間通信機制,可以使用 DPDK Ring API,它是一個無鎖的 ring 實現。該 Ring 機制支持批量和突發訪問,即使同時讀取幾個對象,也只需要一個昂貴的原子操作,批量訪問可以極大地改善性能。

設置正確的目標 CPU 類型與模式

DPDK 支持 CPU 微架構級別的優化,可以通過修改 DPDK 配置文件中的 CONFIG_RTE_MACHINE 參數來定義。優化的程度根據隨編譯器的能力而不同,通常建議採用最新的編譯器進行編譯。如果編譯器的版本不支持該款 CPU 的特性,比如 Intel AVX 指令,那麼它在編譯時只會選用自己支持的指令集,這可能導致編譯後生成的 DPDK 應用的性能下降。

優化方案

筆者在 DPDK 的優化方面的實踐因爲商業敏感的問題,本文不便提及。網上有很多資料,推薦閱讀這一篇文章 https://zhaozhanxu.com/2016/08/09/DPDK/2016-08-09-dpdk-optimization/ 和《DPDK 技術白皮書》。

應用 NUMA 親和性技術減少跨 NUMA 內存訪問

在這裏插入圖片描述
在 NUMA(Non-Uniform Memory Access,非一致性存儲器訪問)架構的處理機中,CPU 訪問本地內存(同 NUMA)和遠程內存(跨 NUMA)的耗時並不相同,NUMA “非一致性存儲器訪問” 架構由此得名。

NUMA 的結構設計能夠在一定程度上解決 SMP 低存儲器訪問帶寬的問題。假如一個 4 NUMA 節點的系統,每一個 NUMA 節點內部都具有 1GB/s 的存儲帶寬,外部共享總線也同樣具有 1GB/s 的帶寬。理想狀態下,如果所有的 CPU 總是訪問本地內存的話,那麼系統就擁有了 4GB/s 的存儲帶寬能力。此時的每個 NUA 節點都可以近似的看作爲一個 SMP(這種假設爲了便於理解,並不完全正確);相反,在最不理想的情況下,如果所有處理器總是訪問遠程內存的話,那麼系統就只能有 1GB/s 的存儲器訪問帶寬。

除此之外,使用外部共享總線時可能會觸發 NUMA 節點間的 Cache 同步損耗,這會嚴重影響內存密集型工作負載的性能。當 I/O 性能至關重要時,外部共享總線上的 Cache 資源浪費,會讓連接到遠程 PCIe 總線上的設備(不同 NUMA 節點間通信)作業性能急劇下降。

由於這個特性,基於 NUMA 架構開發的應用程序應該儘可能避免跨 NUMA 節點的遠程內存訪問。因爲,跨節點內存訪問不僅通信速度慢,還可能需要處理不同節點間內存、緩存的數據一致性問題。多線程在不同 NUMA 節點間的切換,是需要花費大成本的。

應用 CPU 綁核技術減少上下文切換損耗

現代操作系統都是基於分時調用方式來實現任務調度,多個進程或線程在多核處理器的某一個核上不斷地交替執行。每次切換過程,都需要將處理器的狀態寄存器保存在堆棧中,並恢復當前進程的狀態信息,這對系統其實是一種處理開銷。將一個線程固定一個核上運行,可以消除切換帶來的額外開銷。另外將進程或者線程遷移到多核處理器的其它核上進行運行時,處理器緩存中的數據也需要進行清除,導致處理器緩存的利用效果降低

CPU 親和技術,就是將某個進程或者線程綁定到特定的一個或者多個核上執行,而不被遷移到其它核上運行,這樣就保證了專用程序的性能。DPDK 使用了 Linux pthread 庫,在系統中把相應的線程和 CPU 進行親和性綁定,然後相應的線程儘可能使用獨立的資源進行相關的數據處理。

應用大頁內存技術減少 TLB miss

處理器的內存管理包含兩個概念:物理內存和虛擬內存。Linux 操作系統裏面整個物理內存按幀(Frames)來進行管理,虛擬內存按照頁(Page)來進行管理。內存管理單元(MMU)完成從虛擬內存地址到物理內存地址的轉換。內存管理單元進行地址轉換需要的信息保存在
一個叫頁表(Page Table)的數據結構裏面,頁表查找是一種極其耗時的操作。爲了減少頁表的查找過程,Intel 處理器實現了一塊緩存來保存查找結果,這塊緩存被稱爲 TLB(Translation Lookaside Buffer),它保存了虛擬地址到物理地址的映射關係。所有虛擬地址在轉換爲物理地址以前,處理器會首先在 TLB 中查找是否已經存在有效的映射關係,如果沒有發現有效的映射,也就是 TLS miss,處理器再進行頁表的查找。頁表的查找過程對性能影響極大,因此需要儘量減少 TLB miss 的發生。

x86 處理器硬件在缺省配置下,頁的大小是 4K,但也可以支持更大的頁表尺寸,例如 2M 或 1G 的頁表。使用了大頁表功能後,一個 TLB 表項可以指向更大的內存區域,這樣可以大幅減少 TLB miss 的發生。早期的 Linux 並沒有利用 x86 硬件提供的大頁表功能,僅在 Linux 內核 2.6.33 以後的版本,應用軟件纔可以使用大頁表功能。DPDK 則利用大頁技術,所有的內存都是從 HugePage 裏分配,實現對內存池(Mempool)的管理,並預先分配好同樣大小的 mbuf,供每一個數據包使用。

DPDK 目前支持了 2M 和 1G 兩種 HugePage。通過編輯 /etc/grub.conf 來設置:

default_hugepagesz=1G hugepagesz=1G hugepages=32 isolcpus=0-22

然後,執行下述指令,將 HugePage 文件系統 hugetlbfs 掛載到 /mnt/huge 目錄:

mount –t hugetlbfs nodev /mnt/huge

如此,用戶進程就可以使用 mmap() 系統調用映射 HugePage 目標文件來使用大頁面了。測試表明應用程序使用大頁表比使用 4K 的小頁表性能提高 10%~15%。

NOTE:大頁內存的具體介紹可以參見 Linux 的大頁表文件系統(hugetlbfs)特性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章