[developmemt][dpdk] dpdk優化(轉)


轉發:https://software.intel.com/en-us/articles/dpdk-performance-optimization-guidelines-white-paper

轉發:http://zhaozhanxu.com/2016/08/09/DPDK/2016-08-09-dpdk-optimization/

注:本文是參照了一些其他文章,原文地址點擊這里

首先根據這篇文章進行了性能瓶頸的分析

策略與方法


首先根據木桶原理,首先要找到最弱的地方,怎么找往上看↑。

想能優化需要考慮如下:

  • 優化BIOS設置
  • 有效的分配NUMA資源
  • 優化Linux配置
  • 運行l3-fwd程序驗證以上的配置,和公布的性能對比
  • 運行micro-benchmarks選出最佳的更性能組件(比如bulk enqueue/bulk dequeue相對於single enqueue/single dequeue)
  • 從dpdk的例子中找一個接近於你想要寫的程序,按照上面的默認配置來(比如TX buffers資源比RX多)
  • 適配和更新應用程序,使用正確的優化標志編譯
  • 配置你選擇的應用程序,以便有一個比較的基礎
  • 運行優化過的命令行參數
  • 怎樣為架構匹配更好的應用和算法?運行分析找到內存綁定?I/O綁定?CPU綁定?
  • 應用相應的解決方案,軟件內存預取,IO的阻塞模式,CPU綁定超線程或者不
  • 重新運行分析,找出是前端pipeline影響還是后端pipeline影響
  • 應用正確的解決方案。編寫更加有效的代碼-分支預測(likely),循環展開,編譯優化等等
  • 沒有得到期望的性能,回到上面運行優化過的命令行參數,再來一次
  • 記錄容易記住的方法,分享到dpdk官網

優化BIOS設置


NUMA ENABLED
Enhanced Intel® SpeedStep® technology DISABLED
Processor C3 DISABLED
Processor C6 DISABLED
Hyper-Threading ENABLED
Intel® Virtualization Technology for Directed I/O DISABLED
MLC Streamer ENABLED
MLC Spatial Prefetcher ENABLED
DCU Data Prefetcher ENABLED
DCU Instruction Prefetcher ENABLED
CPU Power and Performance Policy Performance
Memory Power Optimization Performance Optimized
Memory RAS and Performance Configuration -> NUMA Optimized ENABLED

請注意,如果要使用DPDK電源管理功能,必須啟用EnhancedIntel®SpeedStep®技術。 此外,應啟用C3和C6。

平台優化


平台優化包括配置內存和I/O(NIC卡)以利用affinity實現更低的延遲。

NUMA & Memory Controller

舉個多socket插座的例子, 對於在CPU0上運行的線程,socket0訪問local memory延遲較低,通過QPI(Intel® QuickPath Interconnect)訪問remote memory延遲較高,盡量避免。

avatar

問題:
在BIOS中NUMA設置為DISABLED會發生神馬?內存控制器通過socket交叉訪問。例如,如下所示,CPU0正在讀取256個字節(4個高速緩存行)。 由於BIOS NUMA設置為DISABLED狀態,因為內存控制器交叉存取在256個字節之內的訪問,從本地存儲器讀取128字節,從遠程存儲器讀取128字節。遠程內存訪問最終跨越QPI鏈路。這樣做的影響是訪問遠程內存的訪問時間增加,從而導致性能降低。

avatar

解決方案:
如下圖所示,BIOS設置NUMA = Enabled,所有訪問都進入相同的socket(local)內存,沒有QPI交叉。存儲器訪問的延遲較,低性能提高。

avatar

PCIe* Layout and IOU Affinity

avatar

avatar

Linux優化


使用isolcpus減少上下文切換

為了減少上下文切換的可能性,需要提示內核,禁止將其他用戶空間任務調度到DPDK應用線程所在核。isolcpus Linux內核參數用於此目的。

例如,如果DPDK應用程序要在邏輯核心1,2和3上運行,則應將以下內容添加到內核參數列表中:
isolcpus = 1,2,3

注意:即使使用isolcpus提示,調度程序仍可以在隔離的核心上調度內核線程。請注意,isolcpus需要重新啟動。

適配和更新應用程序


現在已經將相關示例應用程序標識為構建最終產品的起點,以下是要回答的下一組問題。

如何配置應用程序以獲得最佳性能?

  • 每個端口可以配置多少個隊列?
  • Tx資源可以分配為與Rx資源相同的大小嗎?
  • 閾值的最佳設置是什么?

建議:好消息是,示例應用程序不僅具有優化的代碼流,而且優化的參數設置為默認值。建議在Tx和Rx的資源之間使用類似的比例。以下是Intel® Ethernet Controller 10 Gigabit 82599的參考和建議。對於其他NIC控制器,請參閱相應的數據手冊。

每個端口可以配置多少個隊列?

有關此主題的詳細測試設置和配置,請參閱白皮書評估軟件路由器的服務器網卡的適用性

下面的圖(從上面的白皮書)指示每個端口不使用多於2到4個隊列,因為性能隨着更高數量的隊列而降低。

對於最佳情況,建議每個端口使用1個隊列。 如果需要更多,可以考慮每個端口2個隊列,但不能超過2個。

avatar

Tx資源可以分配為與Rx資源相同的大小嗎?

為Tx和Rx分配相等大小的資源是一種自然的趨勢。 然而,請注意,http://dpdk.org/browse/dpdk/tree/examples/l3fwd/main.c顯示,Tx ring描述符的數量的最佳默認大小是512,而Rx ring描述符是128.因此,Tx ring描述符的數量是Rx ring描述符的4倍。

avatar

建議選擇Tx ring描述符是Rx ring描述符的4倍,而不是讓它們具有相等的大小。

avatar

## 閾值的最佳設置是什么?

例如,http://dpdk.org/browse/dpdk/tree/app/test/test_pmd_perf.c具有以下針對Intel Ethernet Controller 10 Gigabit 82599的優化默認參數。

avatar

更詳細的說明,請參閱Intel Ethernet Controller 10 Gigabit 82599 data sheet

Rx_Free_Thresh - 快速總結和關鍵點:PCIe處理(更新硬件寄存器)的成本可以通過處理批量的數據包(在更新硬件寄存器之前)攤銷。

Rx_Free_Thresh - 詳細:如下所示,由硬件接收的報文使用報文描述符的循環緩沖器來完成。在循環緩沖器中可以有多達64K-8個描述符。硬件維護卷影副本,包括已完成但尚未存儲在內存中的那些描述符。

RDH(Receive Descriptor Head register)表示正在進行的描述符。

RDT(Receive Descriptor Tail register)表示超出硬件可以處理的最后一個描述符的位置。 這是軟件寫入第一個新描述符的位置。

avatar

在運行時,軟件處理描述符,並在描述符完成后,RDT+1。 然而,在軟件處理每個分組之后更新RDT具有成本,因為其增加了PCIe操作。

Rx_free_thresh表示DPDK軟件在將其發送回硬件之前將保持的空閑描述符的最大數量。 因此,通過在更新RDT之前批量處理報文,我們可以減少該操作的PCIe成本。

使用您的配置的rte_eth_rx_queue_setup()函數中的參數進行微調

1
2
3
ret = rte_eth_rx_queue_setup(portid, 0, rmnb_rxd,
socketid, &rx_conf,
mbufpool[socketid]);

使用正確的優化參數編譯


應用相應的解決方案:軟件預取的內存,I/O阻塞,超線程或不超線程為CPU綁定的應用程序。

內存的軟件預取有助於降低存儲器延遲。

PREFETCHW:預期寫數據時預取到高速緩存:CPU Haswell的新指令,幫助優化降低內存延遲並改善網絡堆棧。

PREFETCHWT1:意圖寫入的預取提示T1(L1高速緩存):CPU Haswell的新指令,意圖寫入提示(使數據通過所有權請求進入“獨占”狀態),將數據提取到指定的高速緩存層級中的位置和位置提示。

有關這些說明的更多信息,請參閱Intel® 64 and IA-32 Architectures Developer’s Manual

使用優化的命令行參數運行


優化應用程序命令行選項,提高affinity、locality和並發性。

coremask參數

coremask參數指定lcore運行DPDK應用程序。更高的性能,降低處理器間通信成本是關鍵。這樣的溝通的核心是物理的鄰居,應該選擇coremask。

問題︰ DPDK的命令行coremask參數指定了lcore 0和lcore 1兩個相鄰芯。請注意,這些lcore號分別映射到指定的NUMA sockets上。不同的平台是不一樣的,這個平台上可能lcore 0和1是鄰居,有些平台可能不是。

如下圖所示,在單socket,lcore 0和lcore 4是相同的物理core(core 0)的兄弟姐妹。所以lcore 0和 lcore 4之間的通信成本低於lcore 0和lcore 1之間的通信成本。

avatar

解決方案:不同的平台布局的時候需要注意使用不同的方案。

查看CPU布局的工具

通過tools目錄的./cpu_layout.py能找出socket ID,物理core ID,lcore ID。根據這些信息來確定coremask參數怎么確定。

dual-socket機器我們看到的CPU布局如下:
物理core為[0, 1, 2, 3, 4, 8, 9, 10, 11, 16, 17, 18, 19, 20, 24, 25, 26, 27]
注意物理core 5, 6, 7, 12, 13, 14, 15, 21, 22, 23不在上面的范圍中,這表明物理核心不一定是連續的。

怎么從cpu布局中找到哪些lcores是超線程的?
在下圖中,lcore 1和lcore 37是socket 0的超線程,將通信任務分配給lcore 1和lcore 37比分配給其他的lcore有更低的消耗和更高的性能。

avatar

core 0留給Linux,別給DPDK用

DPDK初始化中,master core默認使用的是lcore 0。如下圖所示

avatar

DPDK應用程序盡量不使用lcore 0,因為Linux 把lcore 0作為master core。避免使用l3fwd – c 0x1…,因為這會使用lcore 0。相反,應用程序可以使用lcore 1,命令行為l3fwd — — c 0x2……。

實際使用OVS-DPDK的情況下,控制平面線程綁定lcore 0,負責響應用戶或SDN控制器發出的控制平面命令。所以,DPDK應用程序不應使用lcore 0,設置掩碼的時候不激活lcore 0。

正確使用channel參數

要確保正確使用channel參數。例如,使用channel參數n = 3表示3通道內存系統。

avatar

avatar

DPDK Micro-benchmarks and auto-tests


auto-tests用於功能驗證。以下是幾個micro-benchmarks性能評價的例子。

怎么測試兩個core的cache line往返消耗的時間

http://dpdk.org/browse/dpdk/tree/app/test/test_distributor_perf.c中的函數Time_cache_line_switch()就是用來測試兩個core的cache line往返所需要的cpu cycles。

怎么測試報文處理時間

http://dpdk.org/browse/dpdk/tree/app/test/test_distributor_perf.c中的函數Perf_test()一次發送32個報文,最后工作線程記錄收到最后一個報文的時間,然后計算出每個報文消耗的時間。

avatar

怎么檢測single producer/single consumer(sp/sc)和multi-producer/multi-consumer(mp/mc)之間的性能差異

運行/app/test中的ring_perf_auto_test,會輸出cpu cycles,來對比不同bulk下sp/sc和mp/mc的差別。

關鍵點:高bulk下,sp/sc有更高的性能。

注意,默認ring_perf_auto_test貫穿塊大小8-32的性能測試,但是如果想自定義,需要修改數組bulk_size[]。下圖輸出了1、2、4、8、16、32的塊大小。

2-Socket System – Huge Page Size = 2 Meg

avatar

avatar

avatar

avatar

hash_perf_autotest為每個測試項運行1000000次迭代,改變以下的參數並且為每個組合總結出每次操作所用的時鍾滴答(Ticks/Op)

Hash Function Operation Key Size (bytes) Entries Entries per Bucket
a) Jhash,
b) Rte_hash_CRC
a) Add On Empty,
b) Add Update,
c) Lookup
a) 16,
b) 32,
c) 48,
d) 64
a) 1024,
b) 1048576
a) 1,
b) 2,
c) 4,
d) 8,
e) 16

附錄有詳細的測試輸出和命令,您可以使用來評估您的平台的性能。摘要結果制成表格下, 圖︰

avatar

avatar

Sl No. Focus Area to Improve Use These Micro-Benchmarks and Auto-Tests
1 Ring For Inter-Core Communication 單獨enqueue/dequeue和批量enqueue/dequeue之間的性能對比
分別對比不同的超線程、cores、sockets上的兩個core之間的批量enqueue/dequeue
空ring上dequeue的性能test_ring_perf.c
Single producer, single consumer – 1 Object, 2 Objects, MAX_BULK Objects – enqueue/dequeue
Multi-producer, multi-consumer – 1 Object, 2 Objects, MAX BULK Objects – enqueue/dequeue
使用test_ring.c驗證以上幾項
test_pmd_ring.c分驗證Tx Burst和Rx Burst
2 Memcopy 使用test_memcpy_perf.c分別驗證以下幾項:
Cache to cache
Cache to memory
Memory to memory
Memory to cache
3 Mempool 使用test_mempool.c驗證以下幾項的n_get_bulkn_put_bulk
1 core, 2 cores, max cores with cache objects
1 core, 2 cores, max cores without cache objects
4 Hash 使用test_hash_perf.c驗證Rte_jhashrte_hash_crc的以下幾項
Add, Lookup, Update
5 ACL Lookup test_acl.c
6 LPM test_lpm.c
7 Packet Distribution test_distributor_perf.c
8 NIC I/O Benchmark Benchmarks Network I/O Pipe - NIC h/w + PMD
Measure Tx Only
Measure Rx Only
Measure Tx & Rx
9 NIC I/O + Increased CPU processing Increased CPU processing – NIC h/w + PMD + hash/lpm Examples/l3fwd
10 Atomic Operations/ Lock-rd/wr test_atomic.ctest_rwlock.c
11 SpinLock 使用test_spinlock.c驗證以下兩項:
申請全局鎖,做些操作,釋放全局鎖
申請per-lcore鎖,做些操作,釋放per-core鎖
12 Software Prefetch test_prefetch.c用法為:rte_table_hash_ext.c
13 Reorder and Seq. Window test_reorder.c
14 ip_pipeline 用packet framework創建一個pipeline,test_table.c
ACL Using Packet Framework,test_table_acl.c
15 Reentrancy test_func_reentrancy.c
16 mbuf test_mbuf.c
17 memzone test_memzone.c
18 Ivshmem test_ivshmem.c
19 Virtual PMD virtual_pmd.c
20 QoS test_meter.c,test_red.c,test_sched.c
21 Link Bonding test_link_bonding.c
22 Kni 使用test_kni.c驗證以下幾項:
傳輸、從kernel接收、kernel請求
23 Malloc test_malloc.c
24 Debug test_debug.c
25 Timer test_cycles.c
26 Alarm test_alarm.c

編譯優化


可以參考圖書Pyster - Compiler Design and construction

性能優化和弱有序注意事項


背景︰Linux內核的同步原語包含所需的內存屏障如下所示(單處理器和多處理器的版本)

Smp_mb() 內存屏障
Smp_rmb() 讀內存屏障
Smp_wmb() 寫內存屏障
Smp_read_barrier_depends() 強制后續的操作是依賴與之前的操作,保證有序性
Mmiowb() 全局spinlocks保障有序的MMIO寫操作

使用標准同步原語(spinlocks, semaphores, read copy update)的代碼不必使用內存屏障,因為這些標准的同步原語已經使用了內存屏障。

挑戰:如果你寫的代碼沒有使用標准的同步原語,而又想優化,可以使用內存屏障。

考慮:X86提供了process ordering的內存模型,他是弱一致性的,可以任意打亂順序,除非有內存屏障限制。

smp_mp(), smp_rmb(), smp_wmb()原語禁止編譯器優化,避免內存重新排序優化跨過內存屏障的影響。

一些SSE指令是弱有序的(clflush and non-temporal move instructions),帶有SSE指令的CPU mfence類似smp_mb(),lfence類似smp_rmb(),sfence類似smp_wmb()。

附錄


Pmd_perf_autotest

使用/app/test/pmd_perf_autotest評估你的平台性能

關鍵點:每個報文RX+TX的開銷是54 cycles,4端口4內存通道

avatar

只查看RX的開銷,運行程序pmd_perf_autotest之前先運行set_rxtx_anchor rxonly,同樣只查看TX的開銷,運行set_rxtx_anchor txonly

Packet Size = 64B # of channels n= 4

of cycles per packet TX+RX Cost TX only Cost Rx only Cost
With 4 ports 54 cycles 21 cycles 31 cycles

下圖是TX和RX的數據

avatar

avatar

avatar

Hash Table Performance Test Results

運行/app/test/hash_perf_autotest評估系統性能。

avatar

avatar

avatar

avatar

avatar

Memcpy_perf_autotest Test Results

運行/app/test/memcpy_perf_autotest評估平台系統性能,分別有32位對齊和未對齊的情況

avatar

avatar

avatar

Mempool_perf_autotest Test Results

Core Configuration Cache Object Bulk Get Size Bulk Put Size of Kept Objects
a) 1 Core
b) 2 Cores
c) Max. Cores
a) with cache object
b) without cache object
a) 1
b) 4
c) 32
a) 1
b) 4
c) 32
a) 32
b) 128

運行/app/test/mempool_perf_autotest評估平台系統性能

avatar

avatar

## Timer_perf_autotest Test Results

of Timers Configuration Operations Timed
a) 0 Timer
b) 100 Timers
c) 1000 Timers
d) 10,000 Timers
e) 100,000 Timers
f) 1,000,000 Timers
- Appending
- Callback
- Resetting

運行/app/test/timer_perf_autotest評估平台系統性能

avatar

avatar


免責聲明!

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



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