DPDK Mempool 庫原理(學習筆記)


1 前置知識點學習(了解)

從CPU到實際的存儲節點,依據層級划分:Channel > DIMM > Rank > Chip > Bank > Row /Column

clipboard

1.1 channel

CPU到內存的通路是channel,每個channel對應一個CPU的內存控制器,每個channel可以配有多個DIMM。

雙通道:CPU外核或北橋有兩個內存控制器,每個控制器控制一個內存通道。理論上內存帶寬增加一倍。

四通道同理。

1.2 DIMM

全稱Dual-Inline-Memory-Modules(雙列直插式存儲模塊),是目前最常見的內存模塊( 可以理解為內存條)。

以前的主機是直接將存儲芯片(chip)插在主板上的,然后發展出SIMM(Single In-line Memory Module),將多個chip焊在一片電路板上,成為內存模塊,再將它插到主板上。

1.3 Rank

DIMM上一部分或所有chip組成一個rank(64bit),因此內存至少需要有16片4bit的chip或者8bit的chip(不存在4bit和8bit芯片混搭的情況)。

內存控制器只允許CPU每次與內存進行一組64bits的數據交換,對應的就是一個rank。rank也可以理解為連接到同一個CS(chip select)的一組chip。

rank分類:

  • Single-Rank(1R),要動用到DIMM上所有的chip,這些chip由同一個片選信號控制。
  • Double-Rank(2R),產生2個64位rank,由2個片選信號控制,這2個片選信號是交錯的,不爭搶內存總線。
  • Quad-Rank(4R),產生4個64位rank,由4個片選信號控制,這4個片選信號是交錯的,不爭搶內存總線。

在地址選擇時,只有當片選信號有效時,此片所連的地址線才有效。

1.4 chip

內存條上的黑色芯片就是chip,提供4bit/8bit/16bit/32bit的數據,提供4bit的芯片記作x4,提供8bit的芯片記作x8。

1.5 其他

再往下的bank、Row /Column這里可以暫時不用關心了,通過上文的示意圖中了解一下就行。

2 DPDK Mempool 庫

內存池是一個具有固定大小的對象分配器。 在DPDK中,它由名稱唯一標識,並且使用mempool handler來存儲空閑對象。 默認的mempool handler是基於ring的。它提供了一些可選的服務,例如“per-core緩存”和“內存對齊”,內存對齊能確保對象被填充,以在所有DRAM或DDR3通道上均勻分布。

這個庫由 Mbuf Library 使用。

2.1 Cookies保護字段

在調試模式中(CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG is enabled),將在塊的開頭和結尾處添加cookies。 分配的對象包含保護字段,以幫助調試緩沖區溢出。

2.2 Stats統計信息

在調試模式中(CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG is enabled),從池中獲取、釋放的統計信息存放在mempool結構體中。 為了避免並發訪問統計計數器,統計信息是per-lcore的。

2.3 內存對齊約束

根據X86架構上的硬件內存配置,可以通過在對象之間添加特定的填充來極大地提高性能。目的是確保每個對象的起始位置被均勻的分布在不同的channel和rank上,以便實現所有通道的負載均衡。

當執行L3轉發或流分類時,對於包緩沖區尤其如此。只訪問前64個字節,因此可以通過將對象的開始地址分布在不同的通道中來提高性能。

DIMM上的rank數目是可訪問DIMM完整數據位寬的獨立DIMM集合的數量。 由於他們共享相同的路徑,因此rank不能被同時訪問。 DIMM上的DRAM芯片的物理布局不一定與rank數目相關。

當運行app時,EAL命令行選項提供了添加內存通道和rank數目的能力。

注:命令行必須始終指定處理器的內存通道數目。

不同DIMM架構的對齊示例如下兩張圖所示 。在例子中,我們假設包是16個64字節的塊(在實際應用中這是不正確的)。

例1:Two Channels and Quad-ranked DIMM Example

例2:Three Channels and Two Dual-ranked DIMM Example

Intel® 5520芯片組有三個通道,因此,在大多數情況下,對象之間不需要填充。(除了大小為n x 3 x 64B的塊)

當創建一個新池時,用戶可以指定使用此功能。

我的疑問:

這里的例子是從dpdk官網拷貝過來的,我有個疑問,如果有誰知道麻煩給我留言。

例2中的pkt0根據圖上看明明是starts at channel 0, rank0,為什么圖上標注的是rank1?如果從圖上看,這里只保證了起始於不同channel,但仍是同一個rank而且是同一個DIMM。根據原文描述,pkt只要不是n x 3 x 64B的大小就不需要填充,感覺只是保證起始在不同channel就可以了。這個問題搜索了很久沒有滿意的答案。

2.4 本地緩存

在CPU使用率方面,由於每個訪問需要compare-and-set (CAS)操作,所以多核訪問內存池的空閑緩沖區成本比較高。 為了避免對內存池ring的訪問請求太多,內存池分配器可以維護per-core cache,並通過實際內存池中具有較少鎖定的緩存對內存池ring執行批量請求。 通過這種方式,每個core都可以訪問自己空閑對象的緩存(帶鎖), 只有當緩存填充時,內核才需要將某些空閑對象重新放回到緩沖池ring,或者當緩存空時,從緩沖池中獲取更多對象。

雖然這意味着一些buffer可能在某些core的緩存上處於空閑狀態,但是core可以無鎖訪問其自己的緩存提供了性能上的提升。

緩存由一個小型的per-core表及其長度組成。可以在創建池時啟用/禁用此緩存。

緩存大小的最大值是靜態配置,並在編譯時定義的(CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE)。

不同於per-lcore內部緩存,應用程序可以通過接口 rte_mempool_cache_create() , rte_mempool_cache_free() 和 rte_mempool_cache_flush() 創建和管理外部緩存。 這些用戶擁有的緩存可以被顯式傳遞給 rte_mempool_generic_put() 和 rte_mempool_generic_get() 。 接口 rte_mempool_default_cache() 返回默認內部緩存。 與默認緩存相反,用戶擁有的高速緩存可以由非EAL線程使用。

2.5 Mempool handlers

這允許外部存儲子系統,如外部硬件存儲管理系統和軟件存儲管理與DPDK一起使用。

mempool handler包括兩方面:

  • 添加新的mempool操作代碼。這是通過添加mempool ops代碼,並使用 MEMPOOL_REGISTER_OPS 宏來實現的。
  • 使用新的API調用 rte_mempool_create_empty() 及 rte_mempool_set_ops_byname() 用於創建新的mempool,並制定用戶要使用的操作。

在同一個應用程序中可能會使用幾個不同的mempool處理。 可以使用 rte_mempool_create_empty() 創建一個新的mempool,然后用 rte_mempool_set_ops_byname() 將mempool指向相關的 mempool處理回調(ops)結構體。

傳統的應用程序可能會繼續使用舊的 rte_mempool_create() API調用,它默認使用基於ring的mempool處理。 這些應用程序需要修改為新的mempool處理。

對於使用 rte_pktmbuf_create() 的應用程序,有一個配置設置(RTE_MBUF_DEFAULT_MEMPOOL_OPS),允許應用程序使用另一個mempool處理。

2.6 用例

需要高性能的所有分配器應該使用內存池實現。 以下是一些使用實例:

  • Mbuf Library
  • Environment Abstraction Layer
  • 任何需要在程序中分配固定大小對象,並將被系統持續使用的應用程序


引用參考資料:

1)dpdk官方文檔:http://doc.dpdk.org/guides-20.02/prog_guide/mempool_lib.html

2)RAM結構與原理:https://www.techbang.com/posts/18381-from-the-channel-to-address-computer-main-memory-structures-to-understand

3)DDR掃盲——single rank與dual-rank:https://www.sohu.com/a/168446287_781333


免責聲明!

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



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