1. 程式人生 > >dpdk --- 大頁配置

dpdk --- 大頁配置

(一)一些概念:

分頁:將實體記憶體分成固定大小的塊,按照頁來進行分配和釋放;一般帶下為4K(2^12)個位元組;

大頁:比如大小為2M(2^20)和2G(2^32)位元組大小的頁;

虛擬地址:軟體編碼通過虛擬地址來訪問記憶體;由處理器將虛擬地址轉換成實體地址;(虛擬地址對應虛擬記憶體,虛擬記憶體對應了numa系統的node節點)

頁表:形成頁目錄表、頁表、內容頁的層級結構(為什麼要三層結構?)用於虛擬地址到實體地址的轉換;以虛擬地址2^32舉例:

 

(二)TLB

在分層定址的基礎上,又引入了TLB的概念;TLB可以理解為一個快取在cache中維護著前20位[31:12]對應關係的表項;如果能在TLB中匹配到邏輯地址,就能迅速通過頁表項和[11:0]得到實體地址;反之,無法匹配則為不命中;

既然這樣,如果TLB足夠大,所有表項都快取在cache中,保證每次命中,則轉換過程可以非常快;而實際上TLB表項很小(受限於cache本身的大小?);

(三)大頁

這時候大頁的優勢就體現出來了;通過配置大頁,需要的TLB表項就很小;如果是以2M作為分頁,只需要一個表項就可保證全部命中了~

(四)如何配置大頁

操作環境的NUMA拓撲結構:

可以看到,一共有2個socket(CPU插槽-物理概念),每個socket有2個node,每個node有24個core,每個core單執行緒,共有96個threads。

大頁分配可以通過linux啟動引數設定或者啟動後動態預留。

假設需要在node0上分配1024個2M大頁,在linux中可以通過動態預留:

echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages

dpdk中在node0節點出輸入1024即可:

./home/z00383571/Dpdk_18.05/dpdk-stable-18.05.1/usertools/dpdk-setup.sh

而對於1G大小的頁,必須通過設定啟動引數的方式預留,不支援動態修改:

EulerOS:~ # cat /proc/cmdline
BOOT_IMAGE=hugepagesz=1G default_hugepagesz=1G hugepages=4

(四)dpdk的大頁使用

eal_hugepage_info_init() : //獲取大頁配置
eal_hugepage_info_read(); //根據配置初始化並對映記憶體  更具體的程式碼分析後續單獨記錄

 

使用大頁需要mount到某個路徑,比如:

#mkdir /mnt/huge
#mount -t hugetlbfs nodev /mnt/huge

可以修改/etc/fstab來避免每次開機重新設定

nodev /mnt/huge hugetlbfs defaults 0 0

對於1GB大小的大頁。需要使用如下:

nodev /mnt/huge_1GB hugetlbfs pagesize=1GB 0 0

 

提問1:為什麼需要分成三層的結構去進行查詢?(如果改成兩層,可以減少一次記憶體訪問)

答:依舊以2^32虛擬地址為例,為了管理4K記憶體頁,需要2^20個表項,因此需要建立一個4M的頁表,即1024個物理頁,記憶體代價過大。

提問2:假設pci網絡卡裝置掛在cpu1的pcie總線上,大頁申請在cpu0的node0上,會不會導致轉發效能低?

答:跨socket使用記憶體,必然會導致效能降低;