DPDK 原理


DPDK 入門

DPDK旁路原理

​ 原來內核協議棧的方式數據是從 網卡-->驅動-->協議棧-->socket接口-->業務

​ 而DPDK的方式是基於UIO(Userspace I/O)旁路數據。數據從 網卡-->DPDK輪詢模式-->DPDK基礎庫-->業務

DPDK的基石UIO

為了讓驅動運行在用戶態,linux提供UIO機制,使用UIO可以通過read感知中斷,通過mmap實現核網卡的通訊

UIO原理

要開發用戶態驅動有幾個步驟:

  1. 開發運行在內核的UIO模塊,因為硬中斷只能在內核處理

  2. 通過/dev/uioX讀取中斷

  3. 通過mmap和外設共享內存

DKDP核心優化

DPDK的UIO驅動屏蔽了硬件發出的中斷,然后在用戶態采用主動輪訓的方式,這種模式被稱為PMD(Poll Mode Driver)

UIO 旁路了內核,主動輪訓去掉硬中斷,DPDK從而可以在用戶態做收發包處理。帶來zero copy,無系統調用的好處,同步處理減少上下文切換帶來的Cache MIss。

運行在PMD的CORE會處於CPU100%的狀態。

網絡空閑時CPU 長期空轉,會帶來能耗問題。所以,DPDK推出interrupt DPDK模式。

interrupt DPDK:

DPDK的高性能代碼實現

1. 采用HugePage減少TLB Miss

默認下Linux采用4KB為一頁,頁越小內存越大,頁表的開銷越大,頁表的內存占用也越大。CPU有TLB(Translation Lookaside Buffer)成本高所以一般就只能存放幾百到上千個頁表項。如果進程要使用64G內存,則64G/4KB=16000000(一千六百萬)頁,每頁在頁表項中占用16000000 * 4B=62MB。如果用HugePage采用2MB作為一頁,只需64G/2MB=2000,數量不在同個級別。

而DPDK采用HugePage,在x86-64下支持2MB、1GB的頁大小,幾何級的降低了頁表項的大小,從而減少TLB-Miss。並提供了內存池(Mempool)、MBuf、無鎖環(Ring)、Bitmap等基礎庫。根據我們的實踐,在數據平面(Data Plane)頻繁的內存分配釋放,必須使用內存池,不能直接使用rte_malloc,DPDK的內存分配實現非常簡陋,不如ptmalloc。

2. SNA(Shared-nothing Architecture)

軟件架構去中心化,盡量避免全局共享,帶來全局競爭,失去橫向擴展的能力。NUMA體系下不跨Node遠程使用內存。

3. SIMD(Single Instruction Multiple Data)

從最早的mmx/sse到最新的avx2,SIMD的能力一直在增強。DPDK采用批量同時處理多個包,再用向量編程,一個周期內對所有包進行處理。比如,memcpy就使用SIMD來提高速度。

SIMD在游戲后台比較常見,但是其他業務如果有類似批量處理的場景,要提高性能,也可看看能否滿足。

4. 不使用慢速API

這里需要重新定義一下慢速API,比如說gettimeofday,雖然在64位下通過vDSO已經不需要陷入內核態,只是一個純內存訪問,每秒也能達到幾千萬的級別。但是,不要忘記了我們在10GE下,每秒的處理能力就要達到幾千萬。所以即使是gettimeofday也屬於慢速API。DPDK提供Cycles接口,例如rte_get_tsc_cycles接口,基於HPET或TSC實現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM