1.前言面試
說來想學習DPDK已是好久的事情了,奈何老是被所謂的緊急的事情耽誤,故而決心學習一下,記錄一下以便總結,知道DPDK已是好久以前的事情了,記得曾經一次面試就被問到DPDK報文如何走的,也是被問的一臉懵逼甚是尷尬, 主要是工做中用到會比較多, 我的對DPDK的處理機制也是很感興趣編程
2.DPDK介紹網絡
Intel® DPDK 全稱 __Intel Data Plane Development Kit__,是intel提供的數據平面開發工具集,爲Intel architecture(IA)處理器架構下用戶空間高效的數據包處理提供庫函數和驅動的支持,它不一樣於Linux系統以通用性設計爲目的,而是專一於網絡應用中數據包的高性能處理。其工做在用戶層,取代傳統Linux系統中的網絡數據報文處理。但須要注意的是,DPDK提供的是高性能處理報文的能力,而不是對報文的處理。這也提供了咱們自定義用戶協議棧的能力數據結構
3.DPDK 優點多線程
1)輪詢與中斷架構
起初的純輪詢模式是指收發包徹底不使用任何中斷,集中全部運算資源用於報文處理。DPDK純輪詢模式是指收發包徹底不使用中斷處理的高吞吐率的方 式。DPDK全部的收發包有關的中斷在物理端口初始化的時候都會關 閉,也就是說,CPU這邊在任什麼時候候都不會收到收包或者發包成功的中 斷信號,也不須要任何收發包有關的中斷處理。具體收發包流程參見以後的文章單獨說明。網絡應用中可能存在的潮汐效應,在某些時間段網絡數據 流量可能很低,甚至徹底沒有須要處理的包,這樣就會出如今高速端口 下低負荷運行的場景,而徹底輪詢的方式會讓處理器一直全速運行,明 顯浪費處理能力和不節能。所以在DPDK R2.1和R2.2陸續添加了收包中 斷與輪詢的混合模式的支持,相似NAPI的思路,用戶能夠根據實際應 用場景來選擇徹底輪詢模式,或者混合中斷輪詢模式。並且,徹底由用 戶來制定中斷和輪詢的切換策略,好比何時開始進入中斷休眠等待 收包,中斷喚醒後輪詢多長時間,等等。負載均衡
2)多線程編程:
多線程編程早已不是什麼新鮮的事物了,多線程的初衷是提升總體應用程序的性能,可是若是不加註意,就會將多線程的建立和銷燬開銷,鎖競爭,訪存衝突,cache失效,上下文切換等諸多消耗性能的因素引入進來。爲了進一步提升性能,就必須仔細斟酌考慮線程在CPU不一樣核上的分佈狀況,這也就是常說的多核編程。多核編程和多線程有很大的不一樣:多線程是指每一個CPU上能夠運行多個線程,涉及到線程調度、鎖機制以及上下文的切換;而多核則是每一個CPU核一個線程,核心之間訪問數據無需上鎖。爲了最大限度減小線程調度的資源消耗,須要將Linux綁定在特定的核上,釋放其他核心來專供應用程序使用。DPDK的線程基於pthread接口建立,屬於搶佔式線程模型,受內核 調度支配。DPDK經過在多核設備上建立多個線程,每一個線程綁定到單 獨的核上,減小線程調度的開銷,以提升性能。DPDK的線程能夠做爲控制線程,也能夠做爲數據線程。在DPDK 的一些示例中,控制線程通常綁定到MASTER核上,接受用戶配置,並 傳遞配置參數給數據線程等;數據線程分佈在不一樣核上處理數據包。同時還須要考慮CPU特性和系統是否支持NUMA架構,若是支持的話,不一樣插槽上CPU的進程要避免訪問遠端內存,儘可能訪問本端內存。ide
3)CPU親核性:
當處理器進入多核架構後,天然會面對一個問題,按照什麼策略將 任務線程分配到各個處理器上執行。衆所周知的是,這個分配工做通常 由操做系統完成。負載均衡固然是比較理想的策略,按需指定的方式也 是很天然的訴求,由於其具備肯定性。簡單地說,CPU親和性(Core affinity)就是一個特定的任務要在某 個給定的CPU上儘可能長時間地運行而不被遷移到其餘處理器上的傾向 性。這意味着線程能夠不在處理器之間頻繁遷移。這種狀態正是咱們所 但願的,由於線程遷移的頻率小就意味着產生的負載小。將線程與CPU綁定,最直觀的好處就是提升了CPU Cache的命中 率,從而減小內存訪問損耗,提升程序的速度。在Linux內核中,全部的線程都有一個相關的數據結構,稱爲 task_struct。這個結構很是重要,緣由有不少;其中與親和性相關度最 高的是cpus_allowed位掩碼。這個位掩碼由n位組成,與系統中的n個邏 輯處理器一一對應。具備4個物理CPU的系統能夠有4位。若是這些CPU 都啓用了超線程,那麼這個系統就有一個8位的位掩碼。若是針對某個線程設置了指定的位,那麼這個線程就能夠在相關的 CPU上運行。所以,若是一個線程能夠在任何CPU上運行,而且可以根 據須要在處理器之間進行遷移,那麼位掩碼就全是1。實際上,在Linux 中,這就是線程的默認狀態。DPDK經過把線程綁定到邏輯核的方法來避免跨核任務中的切換開 銷,但對於綁定運行的當前邏輯核,仍然可能會有線程切換的發生,若 但願進一步減小其餘任務對於某個特定任務的影響,在親和的基礎上更 進一步,能夠採起把邏輯核從內核調度系統剝離的方法。函數
4)大頁表:
默認下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。工具
5)無鎖機制:
實際上DPDK內部也有讀寫鎖,LINUX系統自己也支持無鎖操做,而且DPDK內部的無鎖機制實現原理同LINUX系統提供的無鎖機制的實現原理相似。二者都採用無鎖環形隊列的方式,採用環形隊列的好處是,當一個數據元素被用掉後,其他數據元素不須要移動其存儲位置,從而減小拷貝,提升效率。LINUX系統若是僅僅有一個讀用戶和一個寫用戶,那麼不須要添加互斥保護機制就能夠 保證數據的正確性。可是,若是有多個讀寫用戶訪問環形緩衝區,那麼 必須添加互斥保護機制來確保多個用戶互斥訪問環形緩衝區。DPDK的無鎖環形隊列不管是單用戶讀寫仍是多用戶讀寫都不須要使用互斥鎖保護。
5)cache預取:
處理器從一級Cache讀取數據須要3~5個時 鍾週期,二級是十幾個時鐘週期,三級是幾十個時鐘週期,而內存則需 要幾百個時鐘週期。DPDK必須保證全部須要讀取的數據都在Cache中,不然一旦出現Cache不命中,性能將會嚴重降低。爲了保證這點,DPDK採用 了多種技術來進行優化,預取只是其中的一種
6)利用UIO技術:
爲了讓驅動運行在用戶態,Linux提供UIO機制。使用UIO能夠經過read感知中斷,經過mmap實現和網卡的通信
4.數據包處理流程
1)Linux傳統方式處理數據包流程:
硬件中斷--->取包分發至內核線程--->軟件中斷--->內核線程在協議棧中處理包--->處理完畢通知用戶層
用戶層收包-->網絡層--->邏輯層--->業務層
2)DPDK處理數據包流程:
硬件中斷--->放棄中斷流程
用戶層經過設備映射取包--->進入用戶層協議棧--->邏輯層--->業務層
5.學習目標
理解DPDK的內存機制, 以及處理數據包的流程