英特尔DSA-加速DPDK Vhost
1. 介紹
VirtIO是一個虛擬接口標準,用于虛擬機(Virtual Machine, VM)訪問其他設備,如網絡設備和塊設備。一個VirtIO設備由一個運行在主機上的后端和一個存在于虛擬機中的前端組成。
數據面開發工具包(DPDK)的Vhost庫是一個VirtIO網絡設備的后端實現,它被廣泛用于軟件交換機,實現高速地接收來自虛擬機的數據包和傳輸數據包給虛擬機。盡管DPDK Vhost庫已利用多種技術進行了優化(例如,循環解卷和使用內聯函數來避免函數調用開銷),但當數據包較大時,很高比例的CPU計算資源被用于數據包拷貝,從而導致Vhost的數據包發送和接收速速率迅速下降。
英特爾?數據流加速器是第四代英特爾?至強?可擴展處理器(代號Sapphire Rapids)中的高性能數據移動和轉換加速器。它為數據移動提供了高帶寬和低延時,可用于卸載DPDK Vhost中的數據包拷貝操作。
我們在DPDK Vhost中把數據包拷貝交給英特爾數據流加速器,這樣Vhost的處理Core可以避免進行繁重的數據包拷貝。我們還提出了一個異步卸載流水線,使用戶程序能夠將Intel DSA的數據包拷貝和上層業務執行并行起來。我們的實驗表明,當數據包大小超過256字節時,英特爾數據流加速器可以為DPDK Vhost帶來顯著的性能提升。
作者:
胡嘉瑜 姜誠 丁旋 賀星光
2. 概述
DPDK Vhost庫是一個高性能的VirtIO網絡設備的后端實現,它是Open vSwitch中廣泛使用的虛擬網絡接口。在本文的后續章節中,我們將使用“DPDK Vhost” 一詞來指代DPDK Vhost庫。
2.1 DPDK Vhost
DPDK Vhost由一組控制路徑和數據路徑的應用程序編程接口(API)組成??刂坡窂紸PI用于映射VM內存,設置VirtIO Virtqueue,并與VirtIO前端協商功能。通過兩個關鍵的數據平面操作(enqueue和dequeue),數據路徑API用于發送或接收數據包到或從VirtIO前端。在enqueue時,Vhost通過將數據包插入到Virtqueue中實現傳輸數據包到VirtIO前端,而在dequeue時,Vhost通過從Virtqueue中取出數據包實現接收來自VirtIO前端的數據包。因此,至少需要兩個VirtIO Virtqueue才能實現Vhost和VirtIO前端之間的雙向數據傳輸。
一個enqueue或dequeue操作可以分為以下三個子操作,如圖1所示。
首先,從Virtqueue中獲取描述VM內存中可用緩沖區的描述符。然后,從這些描述符中讀取稍后用于數據包操作的內存地址。對于enqueue,這些可用描述符指向可用于存儲數據包的空緩沖區;對于dequeue,可用描述符指向VirtIO前端發送的數據包緩沖區。
其次,對于enqueue,將數據包從主機復制到已獲取的緩沖區;對于dequeue,將數據包從已獲取的數據包緩沖區復制到主機。
最后,將已使用描述符寫回到Virtqueue,并向VM發送通知。
這三個子操作按順序由DPDK Vhost的處理Core執行。在完成enqueue或dequeue操作后,DPDK Vhost的處理Core就可以為應用程序執行上層應用邏輯。
圖1. Enqueue/Dequeue操作流程
DPDK Vhost支持兩種Virtqueue格式:Split Virtqueue和Packed Virtqueue, 分別在VirtIO Spec版本0.95和1. 1中引入。Split Virtqueue 由三部分組成:一個描述符表、一個可用環和一個已用環。與Split Virtqueue 不同,Packed Virtqueue 將 Virtqueue 的三個部分合并為一個, 它只包含一個具有不同描述符格式的描述符環。在下文中,我們將使用Split Virtqueue 來演示enqueue和dequeue操作的工作流程。
Split Virtqueue 由描述符表、可用環和已用環組成。描述符表是描述數據包緩沖區的描述符數組,每個可用環和已用環都是指向描述符表中描述符的索引數組。可用環和已用環之間的區別在于,可用環存儲 Vhost 可用的描述符索引,但使用的環存儲 VirtIO 前端可用的描述符索引。每個環還有一個尾部指針,用于指示 VirtIO 前端(用于可用環)或 Vhost(用于使用環)將放置下一個描述符索引的位置,并且在將描述符索引填充到環后,尾指針會增加。尾部指針分別稱為可用環和已用環的avail_idx和used_idx。
圖2 展示了 ?VirtIO 前端? 發送四個數據的示例? ,Vhost ?將它們從Split Virtqueue 中dequeue 。VirtIO 前端將數據包緩沖區信息存儲在前四個描述符中,即從描述符表中的索引 0 到索引 3。然后它在可用環中填充 0~3,并將avail_idx增加 4。在主機端,Vhost 讀取可用環以獲取四個數據包緩沖區地址,然后將數據包從 VM 內存復制到主機內存中。復制完四個數據包緩沖區后,Vhost 將 0~3 寫回使用的環,并將used_idx增加 4,以通知前端 Vhost 已收到四個數據包緩沖區。
圖2. Split Virtqueue操作示例
2.2?英特爾?數據流加速器?
英特爾數據流加速器(Intel Data Streaming Accelerator, Intel DSA)是第四代英特爾至強可擴展處理器中的高性能數據復制和轉換加速器。工作隊列(Work Queue, WQ)是設備上的存儲空間,用于保存已提交到設備的工作描述符,軟件使用WQ向Intel DSA提交工作。批處理描述符(Batch Descriptor)允許軟件使用單個工作提交操作提交多個工作描述符,對于較小的傳輸長度,批處理描述符能潛在地提高Intel DSA的吞吐量。在DPDK Intel DSA驅動程序中,我們使用的是專用工作隊列(Dedicated Work Queue,DWQ)和批處理描述符。
2.3 動機
作為高效的VirtIO后端實現,DPDK Vhost被廣泛應用于軟件交換機,例如Open vSwitch。盡管DPDK Vhost已經通過各種技術(例如循環展開和內聯函數)進行了優化,但隨著數據包大小的增加,Vhost中的數據包拷貝開始限制性能。我們將典型的DPDK應用程序TestPMD用作主機中的軟件交換機,并通過Vhost PMD端口連接到一個虛擬機。我們研究了Vhost PMD端口中數據包拷貝對主機TestPMD的影響,其實驗配置與第4. 1節相同。通過改變數據包大小,我們通過Linux Perf測量了主機TestPMD的數據包轉發率以及在交換、Virtqueue操作和Vhost中的數據包拷貝中所花費的CPU Core周期的比例。
結果如圖3所示。我們可以看到,較大的數據包會顯著增加數據包拷貝在Core處理中所占的比例。在 1518 字節時,59% 的Core時鐘周期被花費在 Vhost 數據包拷貝中。我們還可以看到,較大的數據包大小意味著? TestPMD 的數據包轉發速率較低。這是因為隨著數據包大小的增加,Vhost 數據包拷貝所花費的Core 時鐘周期也隨之增加,Vhost 數據包拷貝也成為 TestPMD的瓶頸。
圖3. 主機TestPMD的Core時鐘周期分布
3.使用Intel? DSA加速的DPDK Vhost
3.1 簡介
圖4 描述了采用Intel DSA 加速的 DPDK Vhost 的設計視圖。如第2.1節所述,一個enqueue或dequeue操作可以分為兩個子操作:處理Virtqueue和數據包拷貝。VirtIO描述符所占的存儲空間較小,而Core十分擅長對小數據空間的讀和寫,因此Core可以快速地完成處理Virtqueue的更新操作。? 與處理Virtqueue相比,數據包的拷貝會占用更多的Core時鐘周期,尤其是在數據包較大時。因此,在Intel DSA加速的DPDK Vhost方案中,我們將enqueue或dequeue操作中的所有數據包拷貝都卸載到Intel DSA(以藍色箭頭顯示),但將 Virtqueue 的處理仍留給Core(如綠色箭頭所示)。
圖4. 采用Intel DSA 加速的 DPDK Vhost 的設計視圖
此外,在此方案中我們還 提出了一個異步的卸載流水線,使上層應用程序能夠將業務邏輯的處理和Intel DSA的數據包拷貝并行執行,從而提高整體的吞吐量。Intel DSA的異步卸載流水線如圖5 所示。
圖5. 異步卸載流水線
首先,Core查詢Intel DSA以獲取之前提交的、現已完成的數據包拷貝操作,并將拷貝完成的數據包所對應的VirtIO描述符寫回 Virtqueue。值得注意的是,Core不會等待Intel DSA 完成之前提交的所有拷貝操作。其次,Core從 Virtqueue 獲取新的可用的VirtIO描述符,將新的數據包拷貝操作提交到Intel DSA。在此階段之后,Intel DSA立即開始進行數據包拷貝。與此同時,釋放的CPU計算資源就可以執行應用的上層業務邏輯。由此可見,Intel DSA的數據包拷貝和應用的上層業務邏輯可以并行執行,而Intel DSA的拷貝延遲也可以隱藏在上層業務邏輯的處理過程中,從而使應用程序實現更高的吞吐量。
3.2?Virtqueue 和Intel? DSA
3.2.1 Virtqueue和Intel? DSA WQ的映射關系
在Intel DSA 加速的 DPDK Vhost方案中,Virtqueue和Intel DSA WQ的使用支持多對多映射。具體來說,一個Intel DSA WQ可被多個Virtqueue使用,而一個Virtqueue也可同時將數據包拷貝卸載到多個Intel DSA WQ上。圖6展示了此映射關系的一個示例, WQ2 被 Virtqueue2、Virtqueue3 和 Virtqueue4 共享,Virtqueue2 同時使用了兩個 Intel DSA WQ。?
圖6. Virtqueue和Intel DSA WQ的映射關系示例
3.2.2??數據包順序
為了避免enqueue或dequeue之后的數據包亂序,DPDK Vhost總是按照描述符出現在Virtqueue中的順序來處理描述符。然而,在采用Intel DSA加速的DPDK Vhost方案中,為了實現更高的硬件拷貝性能,我們沒有強制每個Intel DSA WQ按順序執行拷貝操作。此外,若一個Virtqueue的數據包拷貝卸載到多個Intel DSA WQ上,Intel DSA也無法保證所有的數據包拷貝按順序完成。故在卸載數據包拷貝到Intel DSA之后,潛在的數據包亂序可能給上層應用帶來嚴重的性能問題。
為了保證enqueue或dequeue操作之后數據包不亂序,我們為每個 Virtqueue 都分配了一個重排序數組,用來追蹤已經由Intel DSA完成拷貝的數據包。在重排序數組中,每個數據包都分配有一個標志位,用以表示是否該數據包的所有拷貝操作都已完成。當Intel DSA完成一個數據包的所有拷貝操作之后,該標志位被置為 “DONE” 。在寫回已經使用完成的VirtIO描述符之前,Vhost Core會遍歷此重排序數組,對于標志位置為DONE的數據包,Vhost Core再將其使用的VirtIO描述符寫回Virtqueue;而一旦遇到未被置為DONE的數據包,Vhost Core就會立即停止為此數據包和后續數據包寫回VirtIO描述符。因此,盡管Intel DSA無法保證數據包拷貝的順序,而借助重排序數組,Vhost Core只會通知VM拷貝全部完成的數據包,從而保證enqueue或dequeue操作后數據包不亂序。
圖7展示了在第2.1節的例子中重排序數組的工作過程。在獲取4個可用描述符后,Vhost Core分別向四個Intel DSA WQ(WQ0、WQ1、WQ2 和 WQ3)提交四個源地址和目標地址對。此時,pkt0、 pkt2 和 pkt3 的拷貝均已完成,但Intel DSA WQ2 未完成 pkt1的拷貝。在重排序數組中,除了pkt1外,其余3個數據包的標識位都被置為DONE。因此,Vhost Core只會將pkt0返回給用戶程序,并將索引0寫回已用環。Intel DSA WQ2 完成 pkt1 后,Vhost Core會將 pkt1、pkt2 和 pkt3 返回給用戶程序,并將索引 1~3 寫回到已用環。
圖7. 數據包拷貝卸載到多個Intel? DSA WQ的示例
3.3DPDK Vhost 異步編程接口
采用Intel DSA加速的DPDK Vhost方案提供了一組異步的應用程序接口(Application Program Interface,API),使上層應用可以將業務邏輯的執行和Intel DSA的拷貝并行執行,從而提高整體的吞吐量。
DPDK Vhost利用DPDK dmadev庫(一個通用的DMA引擎庫)來操作硬件DMA設備。因此,除了 Intel DSA以外,DPDK Vhost還可以支持其他類型的DMA引擎,如Crystal Beach DMA。值得注意的是,DPDK dmadev 庫將每個Intel DSA WQ呈現為一個具有一個虛擬通道的 DMA設備實例。在下文中,我們將使用 “DMA 設備實例” 和 “虛擬通道” 來描述如何使用DPDK Vhost 的異步API。
DPDK Vhost的異步API 由控制路徑API和數據路徑 API組成。在開始數據路徑操作之前,用戶程序需要調用控制路徑API來使能DMA加速,具體需要以下三個步驟。
首先,調用rte_vhost_async_dma_configure()告訴DPDK Vhost 將要使用的全部DMA設備實例和虛擬通道。
其次,在調用rte_vhost_driver_register()時設置RTE_VHOST_USER_ASYNC_COPY標識,用于通知DPDK Vhost準備DMA需要的數據路徑環境。
最后,對于將要使用DMA加速的Virtqueue,在其啟用時(即接收到VHOST_USER_SET_VRING_ENABLE消息),在DPDK Vhost的回調函數vring_state_changed()中調用rte_vhost_async_channel_register()。之后,用戶程序就可以調用異步的數據路徑API將Virtqueue上的數據包拷貝卸載到DMA。
DPDK Vhost的異步數據路徑API包含enqueue操作和dequeue操作。使用enqueue操作的異步API需要兩個 步驟。
1. 首先,調用rte_vhost_submit_enqueue_burst() 以獲取可用的描述符,并將數據包的拷貝操作提交到指定的DMA 設備實例和虛擬通道。在調用rte_vhost_submit_enqueue_burst()之后,DMA 設備便開始執行拷貝操作。
2. 其次,調用rte_vhost_poll_enqueue_completed()以獲取指定的DMA設備實例和虛擬通道上拷貝完成的數據包,并將這些數據包對應的描述符寫回Virtqueue。在調用rte_vhost_poll_enqueue_completed()之后,VirtIO 前端便能接收DMA設備發送完成的數據包。
值得注意的是,用戶程序需要在適當的時候調用 rte_vhost_poll_enqueue_completed()。否則,即使DMA設備已經將數據包拷貝到了VM內存,VirtIO 前端也無法接收到數據包。
dequeue操作的異步API只有rte_vhost_try_dequeue_burst()。rte_vhost_try_dequeue_burst()將新的數據包拷貝操作提交到給定的 DMA 設備實例和虛擬通道。此外,它還會檢查給定的DMA設備以獲取拷貝完成的數據包,并將完成的數據包返回給用戶程序。?
當要禁用Virtqueue 或者銷毀Vhost 設備時,應用程序需要按照以下三個步驟調用控制路徑API以禁用Virtqueue的DMA加速。
首先,等待DMA設備完成Virtqueue 中所有的數據包拷貝操作。這可以通過在 DPDK Vhost的回調函數destroy_device()中調用 rte_vhost_clear_queue() 或在DPDK Vhost 的回調函數 vring_state_changed() 中調用 rte_vhost_clear_queue_thread_unsafe() 來實現。
其次,注銷Virtqueue的DMA加速。這可以通過在 DPDK Vhost的回調函數 destroy_device()中調用 rte_vhost_async_channel_unregister()或在DPDK Vhost 的回調函數 vring_state_changed()中調用rte_vhost_async_channel_register_thread_unsafe() 來實現。
最后,調用rte_vhost_async_dma_unconfigure()通知DPDK Vhost不再使用的DMA 設備實例和虛擬通道。
圖8 給出了使用 DPDK Vhost的異步 API 的一個示例。
圖8. 使用DPDK Vhost的異步API示例
3.4 性能
3.4.1批處理
增加數據包的批處理量可以降低Intel DSA提交任務的平均開銷。在每個enqueue或dequeue操作中,DPDK Vhost以批處理的方式卸載數據包拷貝操作,并利用Intel DSA的批處理描述符提交成批的拷貝操作給硬件。因此,Vhost enqueue或dequeue的批處理大小通常決定Intel DSA 的拷貝批處理大小。通常,DPDK 收發包的批處理大小為 32,故DPDK Vhost 至少可以在Intel DSA的一個批處理描述符中提交32 個拷貝操作,這對于Intel DSA 的數據拷貝是足夠高效的。但在某些情況下,每個 enqueue或dequeue操作的批處理大小可能要小得多,這將增加DPDK Vhost使用Intel DSA的卸載開銷,從而降低DPDK Vhost的性能,尤其在數據包較小時。
3.4.2 數據包大小
將數據包拷貝卸載到Intel DSA可以釋放CPU的計算資源來執行上層應用的業務邏輯,但代價是花費額外的CPU計算資源在準備設備描述符、使能硬件、追蹤異步上下文上。因此,對于長度較小的數據包(比如64字節),軟件拷貝的效率跟高。在這種情況下,Intel DSA的 卸載成本將高于增益,使用Intel DSA反而會導致整體性能的下降。
3.4.3綁定Intel? DSA WQs到Cores
DPDK Vhost 使用Intel DSA WQ時會使用自旋鎖來避免多個線程同時使用一個WQ而造成不可預知的錯誤,這是因為DPDK dmadev 庫不支持多個線程同時安全地訪問一個Intel DSA WQ。因此, 當多個線程同時嘗試使用同一個Intel DSA WQ時,自旋鎖會讓使這些線程忙等、直到獲取鎖為止,這將導致CPU的計算資源浪費在無用的忙等上。因此,用戶程序應當將不同的Intel DSA WQ 綁定給不同的Core,以避免多個線程競爭使用同一個Intel DSA WQ。
4. 性能測試
我們測試了采用Intel DSA加速的主機上的TestPMD的運行性能,并將其與沒有Intel DSA加速的主機上的TestPMD的性能進行了比較。在所有測試中,我們將一個物理Core分配給主機TestPMD。在使用Intel DSA加速的TestPMD 實驗中,我們使用了一個Intel DSA設備。由于測試中使用的DPDK DSA 驅動僅支持DWQ,因此我們為使用的Intel DSA設備創建了兩個DWQ。此外,為了使用一個Intel DSA設備的最大性能,測試中使用了該Intel DSA設備的所有的四個引擎。
4.1 測試方法
圖9. 實驗拓撲
圖9 顯示了實驗拓撲。在主機中,TestPMD 以macfwd模式運行,并綁定了一個E810-CQDA2端口和一個Vhost PMD端口。兩個DWQ分別分配給 Vhost PMD 端口中的TX 隊列和RX 隊列。在客戶機中, TestPMD 以 macfwd 模式運行,并與 VirtIO 端口綁定。Ixia流量生成器連接到 E810-QDA2端口,并以 0.1% 的可接受丟失率發送 TCP/IPv4 數據包。
實驗中使用的硬件列于表3中。
實驗中使用的軟件列于表4中。
4.2 測試結果
圖10比較了采用和不采用Intel DSA 加速的TestPMD 的數據包轉發速率。當數據包大小超過256 字節時,采用Intel DSA 加速的 TestPMD 的數據包轉發速率是沒有Intel DSA 加速的數據包轉發率的1.14-2. 29倍。此外,采用Intel DSA 加速的 TestPMD 可實現從 64字節到 1518字節的固定數據包轉發速率。
通過將數據包拷貝卸載到Intel DSA,TestPMD 只需處理數據包頭部,因此TestPMD Core的處理與數據包大小無關。此外,測試中已使用的Intel DSA 帶寬小于Intel DSA 數據拷貝的最大帶寬。因此,在不同數據包大小時,采用Intel DSA加速的TestPMD的數據包轉發率可以保持恒定。
當數據包的大小小于或等于 256 字節時,采用Intel DSA 加速的 TestPMD 性能會更差。這是由于Core在小數據包拷貝上比Intel DSA更高效,并且使用Intel DSA卸載數據包拷貝操作會引入額外的開銷,因此采用Intel DSA 卸載反而會使TestPMD 的性能下降。
圖10. 數據包轉發速率比較
5. 總結
在本文中,我們概述了采用Intel DSA加速的DPDK Vhost的設計以及DPDK Vhost異步API的使用方法,并在第四代英特爾至強可擴展處理器上測試了帶有Intel DSA加速的TestPMD數據包轉發速率。在數據包大小超過256字節時,將數據包拷貝卸載到Intel DSA可以顯著提高數據包的轉發性能。
Reference
VirtIO Spec Version 0.95
https://ozlabs.org/~rusty/virtio-spec/virtio-0.9.5.pdf
VirtIO Spec Version 1.1
https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html
Intel Data Streaming Accelerator
https://01.org/blogs/2019/introducing-intel-data-streaming-accelerator?
3個patch的信息:
http://patches.dpdk.org/project/dpdk/patch/20221216020009.70206-1-yuanx.wang@intel.com/ http://patches.dpdk.org/project/dpdk/patch/20221011030803.16746-2-cheng1.jiang@intel.com/
http://patches.dpdk.org/project/dpdk/patch/20221011030803.16746-3-cheng1.jiang@intel.com/
點擊文末左下角【閱讀原文】,可獲取本文pdf資源。
轉載須知
DPDK與SPDK開源社區
公眾號文章轉載聲明
推薦閱讀
開源!HDSLB高密度可拓展負載均衡器
綠盟科技天樞實驗室引入英特爾? 流量分析開發工具套件,打造針對Web攻擊的AI高性能檢測方案
云原生邊緣算力平臺白皮書
Release notes for VPP 23.02
點點“贊”和“在看”,給我充點兒電吧~
總結
以上是生活随笔為你收集整理的英特尔DSA-加速DPDK Vhost的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾讯云神笔低代码平台的申请没通过,只能等
- 下一篇: 有什么真无线蓝牙耳机推荐?2022蓝牙耳