(零)DPDK-基礎概念

CPU 中的內存結構

 CPU 和各級緩存、內存、硬盤之間的關係 

緩存一致性:

目前結構每個core都會持有自己私有的L1/L2 Cache, 但 L3 cache是所有core共有的. 那麼就存在一個cache一致性的問題 

MESI 爲了保證多個緩存中共享數據的一致性,定義了 cache line 的四種狀態,而線程對 cache line 的四種操作可能會產生不一致的狀態,

因此緩存控制器監聽到本地操作和遠程操作的時候,需要對地址一致的 cache line 狀態進行一致性修改,從而保證數據在多個緩存之間保持一致性。(M: modified E: Exclusive S: shared I: invalid)

在 MESI 出現之前的解決緩存一致性的方案是總線鎖機制,這種解決方案效率很低,鎖住總線期間,其他 CPU 無法訪問內存

  • Modified(M):  (唯一一份,和主存不一致)(所有其它core對這個cacheline的讀操作必須在該cacheline 寫回主存後, 寫回主存後,狀態變換到share
  • Exclusive(E): (唯一一份,乾淨的和主存一致),可以轉換到shared 或者M,重點是可以轉換到M,也就意味着可以對其修改!
  • Shared(S):    (不止一份,可能在多個core中,乾淨的和主存一致), 隨時會被invalidate.
  • Invalid(I):      (無效)表示這個cacheline 目前不可用

當兩個core同時執行鍼對同一地址的CAS指令時,其實他們是在試圖修改每個core自己持有的Cache line, 假設兩個core都持有相同地址對應cacheline,且各自cacheline 狀態爲S, 這時如果要想成功修改,就首先需要把S轉爲E或者M, 則需要向其它core invalidate 這個地址的cacheline,則兩個core都會向ring bus 發出 invalidate這個操作, 那麼在ringbus上就會根據特定的設計協議仲裁是core0,還是core1能贏得這個invalidate, 勝者完成操作, 失敗者需要接受結果, invalidate自己對應的cacheline,再讀取勝者修改後的值, 回到起點.

我們可以發現MESIF協議大大降低了讀操作的時延,沒有讓寫操作更慢,同時保持了一致性

執行序一致性:

CPU 中的亂序執行優化是處理器爲提高運算速度而做出違背代碼原有順序的優化。雖然順序變,但執行結果是不會變的。

亂序優化就是這樣,爲了提高效率 CPU 做出的優化,這在單核的時候是不會有問題的,但是在多核時代又會出現問題。

能不能亂序肯定有一套規則,這套規則也就是內存屏障

從上可以看出 intel x86架構的CPU上,只有Store-Load亂序,沒有其他亂序 

Store和Load指令的含義:簡單來說,Store就是將處理器緩存中的數據刷新到內存中,Load則是從內存拷貝數據到緩存當中. 

內存屏障分類如下:

StoreLoad Barriers同時具備其他三個屏障的效果,因此也稱之爲全能屏障,是目前大多數處理器所支持的,但是相對其他屏障,該屏障的開銷相對昂貴.在x86架構的處理器的指令集中,lock指令可以觸發StoreLoad Barriers. 

 

UIO/VFIO/DDIO

UIO

一個設備驅動的主要任務有兩個:

1. 讀寫設備的內存 
2. 處理設備產生的中斷

  • 第一個任務,UIO 核心實現了mmap()可以處理物理內存(physical memory),邏輯內存(logical memory),虛擬內存(virtual memory)。UIO驅動的編寫是就不需要再考慮這些繁瑣的細節。
  • 第二個任務,對於設備中斷的應答必須在內核空間進行。所以在內核空間有一小部分代碼用來應答中斷和禁止中斷,但是其餘的工作全部留給用戶空間處理

如果用戶空間要等待一個設備中斷,它只需要簡單的阻塞在對 /dev/uioX的read()操作上。

  • 當設備產生中斷時,read()操作立即返回。
  • UIO 也實現了poll()系統調用,你可以使用select()來等待中斷的發生。select()的超時參數可以用來實現有限時間內等待中斷

對設備的控制還可以通過/sys/class/uio下的各個文件的讀寫來完成。

  • 你註冊的uio設備將會出現在該目錄下。
  • 假如你的uio設備是uio0那麼映射的設備內存文件出現在 /sys/class/uio/uio0/maps/mapX,對該文件的讀寫就是對設備內存的讀寫。

UIO的幾個特點:

  • 一個UIO設備最多支持5個mem和portio空間mmap映射。 
  • UIO設備的中斷用戶態通信機制基於wait_queue實現。
  • 一個UIO設備只支持一箇中斷號註冊,支持中斷共享。

總的來說,UIO框架適用於簡單設備的驅動,因爲它不支持DMA,不能支持多箇中斷線,缺乏邏輯設備抽象能力。

VFIO 

VFIO是一個可以安全的把設備I/O、中斷、DMA等暴露到用戶空間(userspace),從而可以在用戶空間完成設備驅動的框架。用戶空間直接設備訪問,虛擬機設備分配可以獲得更高的IO性能

UIO不支持DMA,所以通過DMA傳輸大流量數據的IO設備,如網卡、顯卡等設備,無法使用UIO框架,VFIO做爲UIO的升級版,主要就是解決了這個問題。

  • IOMMU是一個硬件單元,它可以把設備的IO地址映射成虛擬地址,爲設備提供頁表映射,設備通過IOMMU將數據直接DMA寫到用戶空間。之所以不共用MMU單元,是爲了保證和進程的頁表相互獨立,防止設備訪問進程的任意地址空間。所以VFIO的IOMMU功能保障了安全的非特權級別的用戶態設備驅動機制。
  •  /dev/vfio是一個設備文件,作爲一個IOMMU設備的用戶態呈現。
  • container是內核對象,表示一個IOMMU設備,是一個IOMMU設備的內核態呈現。所以在VFIO中,container是IOMMU操作的最小對象。
  • 在虛擬化場景下,一個物理網卡可能要虛擬成幾個虛擬網卡,或者說虛擬功能設備(VF),這幾個VF共用一個IOMMU,所以VFIO模型增加一個iommu_group的概念,用來表示共享同一個IOMMU的一組device。

VFIO的幾個特點:

  • VFIO設備支持多中斷號註冊。
  • 設備的中斷用戶態通信機制基於eventfd/irqfd實現。用戶通過/dev/vfio設備select/poll/epoll,從而實現中斷從內核態到用戶態的異步事件通知。
  • 支持對物理設備進行邏輯抽象。
  • 僅支持pci intx中斷共享,其他類型中斷不支持共享。
  • VFIO僅支持特定IOMMU設備,如x86與PowerPC平臺的PCI設備和ARM平臺的platform設備

DDIO

DDIO使得外部網卡和CPU通過LLC cache直接交換數據,繞過了內存,增加了CPU處理報文的速度

TLB Cache 和 大頁內存(Hugepages)

TLB

TLB(Translation Lookaside Buffer)稱爲頁表緩衝,是一個存放着頁表緩存(虛擬地址到物理地址的轉換表)的內存管理單元,用於改進虛擬地址到物理地址轉換速度。

TLB是內存裏存放的頁表的緩存,那麼它裏邊存放的數據實際上和內存頁表區的數據是一致的,在內存的頁表區裏,每一條記錄虛擬頁面和物理頁框對應關係的記錄稱之爲一個頁表條目(Entry),同樣地,在TLB裏邊也緩存了同樣大小的頁表條目(Entry)

1:TLB在X86體系的CPU裏的實際應用最早是從Intel的486CPU開始的,在X86體系的CPU裏邊,一般都設有如下4組TLB:

  • 第一組:緩存一般頁表(4K字節頁面)的指令頁表緩存(Instruction-TLB);
  • 第二組:緩存一般頁表(4K字節頁面)的數據頁表緩存(Data-TLB);
  • 第三組:緩存大尺寸頁表(2M/4M字節頁面)的指令頁表緩存(Instruction-TLB);
  • 第四組:緩存大尺寸頁表(2M/4M字節頁面)的數據頁表緩存(Data-TLB);

2:TLB命中和TLB失敗

  • 如果TLB中正好存放着所需的頁表,則稱爲TLB命中(TLB Hit);
  • 如果TLB中沒有所需的頁表,則稱爲TLB失敗(TLB Miss)。
  • 當CPU收到應用程序發來的虛擬地址後,
  • 首先到TLB中查找相應的頁表數據,如果TLB中正好存放着所需的頁表,則稱爲TLB命中(TLB Hit)
  • 接下來CPU再依次看TLB中頁表所對應的物理內存地址中的數據是不是已經在一級、二級緩存裏了,若沒有則到內存中取相應地址所存放的數據。
     

Hugepages

Linux操作系統的大頁內存,主要分爲2M和1G大小。可以從CPU的標識中看出支持大內存頁的類型

  • Linux在內存管理中採用受保護的虛擬地址模式,在代碼中地址分爲3類:邏輯地址、線性地址、物理地址
  • 程序使用具體內存簡單說就是邏輯地址通過分段機制映射轉化爲線性地址,然後線性地址通過分頁機制映射轉化爲物理地址的過程
  • 而在實際使用中,僅將線性地址映射爲物理地址的過程中,需要從內存中讀取至少四次頁目錄表(Page Directory)和頁表 (Page Table),爲了加快內核讀取速度,CPU在硬件上對頁表做了緩存,就是TLB。

線性地址先從TLB獲取高速緩存內存,如果不存在就從內存表獲取,如果有直接的映射,直接從內存讀取,沒有則產生缺頁中斷,從新分配物理內存,或者從硬盤上將swap讀取。具體圖示如下:

普通頁大小是每個4K,如果是4K頁的尋址如下,使用物理內存時需要多級查找才能找到對應的內存

4K的頁表是linux針對一般情況得出的合適大小,然而對於特殊應用可以通過擴大頁表面積提高內存使用效率 

dpdk使用hupage的思想就是讓程序儘量獨佔內存防止內存換出,擴大頁表提高hash命中率,通過hugage技術擴大了該使用的頁表大小,設定爲更適合高頻內存使用程序的狀態,獲得了以下幾點優勢。

  • 無需交換。也就是不存在頁面由於內存空間不足而存在換入換出的問題
  • 減少TLB負載。
  • 降低page table查詢負載

 

CPU的物理核,邏輯核概念 CPU親和性

  • 物理處理器封裝個數 ---->物理CPU數: 幾個CPU
  • 處理器核心數--->CPU核心數 : 一個CPU有幾個core
  • 邏輯處理器數--->邏輯CPU數 : 四核八線程
  • SIBLING:內核認爲的單個物理處理器所有的超線程個數  (SIBLING等於實際物理核數的話,就說明沒有啓動超線程,反之啓用超線程。)
  • 超線程: 利用特殊的硬件指令,把兩個邏輯內核模擬成兩個物理芯片,讓單個處理器都能使用線程級並行計算,採用超線程即是可在同一時間裏,應用程序可以使用芯片的不同部分
  • CPU的親和性---->cpu affinity機制: 也就是說把一個程序綁定到一個物理CPU上

 

NUMA-非一致性內存訪問

這裏寫圖片描述

 傳統架構

“CPU 南北橋”的圖片搜索結果

互斥鎖 mutex   :   只有一個保持着

自旋鎖spinlock:   類似互斥鎖    區別: 互斥等待睡眠 自旋原地循環等待

讀寫鎖 rwlock  :   一個寫多個讀 但不能同時有讀有寫

RCU鎖(Read-Copy Update):讀-複製 更新   對讀寫鎖的一種改進 

  • 讀者不需要獲得任何鎖就可訪問RCU保護的臨界區;拷貝(Copy):寫者在訪問臨界區時,寫者“自己”將先拷貝一個臨界區副本,然後對副本進行修改;更新(Update)

網卡

PCIe

PCI Express(Peripheral Component Interconnect Express)又稱PCIe,它是一種高速串行通信互聯標準。

PCIe規範遵循開放系統互聯參考模型(OSI),自上而下分爲事務傳輸層、數據鏈路層、物理層。

對於特定的網卡,PCIe一般作爲處理器外部接口。

一般網卡採用DMA控制器通過PCIe Bus訪問內存,除了對以太網數據內容的讀寫外,還有DMA描述符操作相關的讀寫,這些操作也由MRd/MWr來完成。

PCIe包格式示例,對於一個完整的TLP包來說,除去有效載荷,額外還有24B的開銷(TLP頭部以16B計算)。 

網卡DMA描述符環形隊列

DMA(Direct Memory Access,直接存儲器訪問)是一種高速的數據傳輸方式,允許在外部設備和存儲器之間直接讀寫數據。數據既不通過CPU,也不需要CPU干預。

整個數據傳輸操作在DMA控制器的控制下進行。網卡DMA控制器通過環形隊列與CPU交互。

環形隊列的內容部分位於主存中,控制部分通過訪問外設寄存器的方式完成。 

轉發操作 

Brust (突發)

Burst爲一次完成多個數據包的收發,通過把收發包複雜的處理過程進行分解,打散成不同的相對較小的處理階段,

把相鄰數據訪問、相似的數據運算集中處理,儘可能減少對內存或者低一級的處理器緩存的訪問次數。(目的)

SIMD

即Single Instruction, Multiple Data,一條指令操作多個數據.是CPU基本指令集的擴展.主要用於提供fine grain parallelism,即小碎數據的並行操作.

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