來源:NSDI 19
作者:Daehyeok Kim and Tianlong Yu, Carnegie Mellon University; Hongqiang Harry Liu, Alibaba; Yibo Zhu, Microsoft and Bytedance; Jitu Padhye and Shachar Raindel, Microsoft; Chuanxiong Guo, Bytedance; Vyas Sekar and Srinivasan Seshan, Carnegie Mellon University
參與編譯:張春海、冉玫美、王澤旺、孫夏
摘要
為實現資源的高效利用和輕量隔離,很多流行的大型雲應用都在逐漸使用容器化。同時,很多數據密集型應用(例如,數據分析和深度學習框架)正在或希望採用RDMA來提高網絡性能。行業趨勢表明,這兩種場景不可避免地會發生衝突。在本文中,我們介紹了FreeFlow,一個為容器雲設計的基於軟體的RDMA虛擬化框架。FreeFlow純粹使用基於軟體的方法,利用商用RDMA NICs實現了虛擬RDMA網絡。與現有的RDMA虛擬化解決方案不同,FreeFlow完全滿足來自雲環境的需求,例如多租戶的隔離、容器遷移的可移植性 、以及控制和數據平面策略的可控制性。FreeFlow對應用程式也是透明的,且使用很小的CPU開銷提供了接近裸機RDMA的網絡性能。在我們對TensorFlow和Spark的評估中,FreeFlow提供了幾乎與裸機RDMA相同的應用性能。
第一章 介紹
大型雲應用開發者一直在追求高性能、低運維成本和高資源利用率,導致容器化和遠程直接內存訪問(RDMA)網絡技術被越來越多的採用。
容器[7,11,6]提供的輕量級隔離和可移植性,降低了部署和管理雲應用的複雜性(從而降低了成本)。因此,現在容器成為管理和部署大型雲應用的實際方式。
因為與基於標準TCP/IP的網絡相比,RDMA網絡能夠提供更高的吞吐量、更低的延遲和更少的CPU佔用,所以許多數據密集型應用(例如,深度學習和數據分析框架)都會採用RDMA [24,5,18,17]。
但不幸的是,這兩種技術趨勢在雲環境中是相互矛盾的。容器化的核心價值是為應用提供高效靈活的管理。為此容器雲需要容器在網絡中具有以下三個屬性:
隔離:每個容器都應該有其專用的網絡命名空間(包括埠空間、路由表、接口等),以消除與同一主機上其他容器的衝突。
可移植性:容器應該使用虛擬網絡與其他容器通信,並且與它的虛擬IP保持關聯,而不管它被調度到哪個主機上或遷移到哪個主機上。
可控性:編排器可以容易地執行控制平面策略(例如,準入控制、路由)和數據平面策略(例如,QoS、計費)。此屬性在(多租戶)雲環境中尤其需要。
對於在雲環境中,自由放置、遷移容器、以及控制每個容器可使用的資源,這些屬性都是必需的。為此,在基於TCP/IP的操作中,網絡可以通過軟體(虛擬)交換機來實現完全虛擬化[15]。
但是,很難對基於RDMA的網絡進行完全虛擬化。RDMA通過將網絡處理卸載到硬體NIC中,繞過內核軟體棧,實現了高網絡性能。 在共享的雲環境中難以修改硬體中的控制平面狀態(例如,路由),同時由於流量直接通過PCIe總線在RAM和NIC之間傳輸,也難以控制數據路徑。
因此,採用這兩種技術的幾個數據密集型應用(例如,TensorFlow [24],CNTK [5],Spark [18],Hadoop [17])僅在專用裸機群集中運行時才使用RDMA; 當在共享的雲環境中運行時,不得不完全摒棄RDMA提供的性能優勢。 當然,使用專用集群來運行應用對於提供商或客戶來說都是不划算的。
本文的目的很簡單:我們希望基於雲環境中的容器化應用能夠像在專用裸機集群中那樣高效地使用RDMA,同時也能實現容器雲中的隔離、可移植性和可控性的要求。
目前還沒有成熟的容器RDMA虛擬化解決方案。表1總結了可能通過擴展來支持容器的一些重要選項,儘管它們未能達到關鍵要求,也可能需要以很大的性能成本為代價進行實現。
例如,基於硬體的I/O虛擬化技術,如SR-IOV[21],具有根本的移植性限制[39,28],因為它們需要重新配置硬體網卡和交換機來支持容器的遷移。控制路徑虛擬化解決方案,例如HyV[39],只操作控制平面命令來實現隔離和可移植性,它們不具有數據流的可見性或可控制性。因此,它們不能靈活地支持雲提供商所需的數據平面策略。軟體仿真RDMA,如SoftRoCE[36],通過在UDP網絡棧上運行RDMA並使用現有的虛擬IP網絡解決方案,可以輕鬆實現隔離、可移植性和可控性,但其性能將受到UDP的限制。
本文提出了一種基於軟體的容器雲虛擬RDMA網絡框架FreeFlow,該框架實現了隔離、可移植性和可控性,並提供了接近裸機RDMA的性能。FreeFlow的核心是運行在每個伺服器上的軟體虛擬交換機,來實現在商業RDMA 網卡上虛擬化RDMA。FreeFlow不需要專門的硬體或基於硬體的I/O虛擬化。軟體虛擬交換機具有對容器間通信的控制路徑(如地址、路由)和數據路徑(如數據流量)的完全訪問權。這種設計理念類似於容器雲中用於TCP / IP網絡的現有軟體虛擬交換機,例如Open vSwitch(OvS)[15],儘管由於RDMA的特性,FreeFlow的實際設計與OvS截然不同。
FreeFlow的設計解決了兩個關鍵挑戰。首先,我們希望FreeFlow對應用程式完全透明。這很有挑戰性,因為RDMA需要網卡來操作內存緩衝區和文件描述符,而容器內的應用程式由於網絡虛擬化而不能直接與網卡交互。我們解決這一問題的關鍵點是,容器本質上是進程,它們可以使用FreeFlow輕鬆共享內存和文件描述符等資源。如果FreeFlow和容器共享相同的內存(§4.3)和文件描述符(§4.4),則底層物理RDMA NIC上的任何操作都將自動在容器內生效。另一個問題是,鑑於應用程式不會協作地創建可共享的資源,因此共享對應用程式透明的資源並不簡單。 我們設計了將資源從不可共享轉換為可共享的方法,對應用程式代碼無需修改或只需很少的修改。
其次,FreeFlow必須提供與裸機RDMA相當的吞吐量和延遲。我們將吞吐量和延遲中的性能瓶頸分別定義為內存複製和進程間通信。我們利用一個零拷貝設計吞吐量(§4.3), 一個共享內存進程間通道與CPU旋轉延遲(§5.2)。同時還優化了FreeFlow來限制CPU開銷。
我們使用標準的微基準測試工具和真實的數據密集型應用程式、Spark和TensorFlow來評估FreeFlow的性能,不需要對它們進行任何修改或只需很小的修改。FreeFlow的性能可與裸機RDMA相媲美,無需太多的CPU開銷。同時,與使用傳統TCP/IP虛擬網絡相比,FreeFlow顯著提高了實際應用程式的性能,吞吐量提高了14.6倍,延遲降低了98%。FreeFlow吸引了多個RDMA解決方案提供商的興趣,並已開放原始碼https://github.com/Microsoft/Freeflow。
第二章 背景
本章簡要介紹了容器和RDMA網絡,以及引出對容器的基於軟體的RDMA虛擬化的需求。
容器和容器網絡:容器正在成為打包和部署數據中心應用程式的實際選擇[30, 27, 25]。容器使用如chroot等機制[4],將應用程式的可執行文件和依賴捆綁在獨立的命名空間中,從而提供輕量級隔離和可移植的解決方案。
大多數容器應用使用微服務架構,並由多個容器組成。例如,Spark [2]中的每個mapper和reducer節點都是一個單獨的容器,TensorFlow[22]中的每個ps節點或worker節點也是一個單獨的容器。容器通過網絡解決方案交換數據。網絡解決方案的設計會影響隔離度和可移植性。
例如,在主機模式網絡中,容器使用其主機的IP和埠空間,並像主機作業系統中的常規進程一樣進行通信。此模式有較差隔離性(例如,埠衝突)和可移植性(例如,遷移到其他主機後,必須更改IP位址和埠)。
因此,許多應用程式使用虛擬模式網絡。在此模式下,容器的網絡命名空間完全隔離,容器通過由主機上的軟體虛擬交換機組成的虛擬(覆蓋)網絡進行通信。因為可以在軟體虛擬交換機中控制到虛擬IP的路由,所以容器的虛擬IP是高度可移植的。由於所有數據流量必須通過虛擬交換機,因此它們可以訪問流量,從而為容器網絡提供完全可控性。這種隔離和可移植性使編排器在容器部署和遷移方面具有完全的靈活性,並且這種可控性使雲提供商能夠在控制和數據層面上實施其策略。
實際上,像Kubernetes [11]這樣的編排器要求使用虛擬網絡模式[12]。許多軟體解決方案可用於為容器提供虛擬網絡結構,例如Weave [23]和Docker Overlay [7]。
RDMA網絡:許多現代應用程式(例如深度學習和數據分析框架)已採用RDMA網絡[18,17,25,5]來獲得比傳統TCP / IP堆棧更高的吞吐量和更低的延遲。RDMA通過將大部分網絡功能卸載到NIC中實現性能的提升,有效地繞過作業系統內核。
表2顯示了使用RDMA進行通信的深度學習應用的性能改進- 訓練Recurrent Neural Network(RNN)語音識別模型。該應用程式首先在具有8個GPU的單臺機器上進行基準測試。當應用程式在具有16個GPU的兩臺計算機上運行時,傳統的TCP/IP網絡成為瓶頸,性能的提升下降。但是使用了RDMA,額外GPU可以顯著提高性能。
上述現象的原因是,RNN訓練任務包含數千個步驟。在每個步驟中,所有GPU都必須對訓練模型參數進行shuffle(即隨機重排列),總流量大約在100MB到10GB。花在通信上的時間實際上是浪費GPU的時間,因為GPU在shuffle期間處於空閒狀態。TCP在這些頻繁和突發的工作負載中表現不佳,而RDMA可以在每次shuffle開始時瞬間爬升到全帶寬。
對於基於軟體的RDMA虛擬化的需求:我們已經注意到了虛擬模式網絡對容器應用程式的好處,即增強的隔離性、可移植性和可控性。同時,RDMA還可以為許多具有微服務架構的應用程式提供顯著的性能提升。
那麼問題是,我們如何將RDMA網絡與需要虛擬模式網絡的容器應用程式結合使用,尤其是在雲環境中。
正如我們之前看到的,RDMA網絡依賴於將大多數網絡功能卸載到NIC。「虛擬化」RDMA網絡的一種可能方法是使用基於硬體的解決方案,例如SR-IOV[21],但是這會限制虛擬模式網絡提供的可移植性。如圖1(a)所示,使用SR-IOV,NIC運行一個簡單的第2層交換機,僅僅執行VLAN轉發。因此,必須在底層物理網絡中直接路由從虛擬網絡生成並發往虛擬網絡的所有分組。同時,將容器C1遷移到主機Host2需要重新配置物理交換機,以將C1的數據包路由到Host2,而不是Host1。此外,在生產中,物理交換機需要維護大量的路由表來管理虛擬網絡中所有容器的路由,這在大規模雲環境中是不可行的。
因此,我們認為,為容器虛擬化RDMA網絡的正確方法是使用軟體交換機,正如它用於虛擬化傳統TCP/IP網絡一樣。如圖1(b)所示,物理網絡只負責提供針對不同主機的數據包,而虛擬網絡路由完全在每個主機內部的軟體交換機中實現,這些交換機與物理網絡無關。軟體交換機可以控制所有尋址和路由,因此在控制層面上提供良好的隔離和可移植性。它還可以在數據層面上實現網絡功能,例如QoS和計量。
第三章 概述
FreeFlow的目標是在每個容器內部提供虛擬接口,應用程式可以通過虛擬接口上的虛擬網絡以未修改的方式使用RDMA。理想情況下,虛擬網絡的性能應接近裸機RDMA,並且控制和數據路徑上的策略都可以靈活地配置為純軟體。在本節中,我們將介紹系統架構以及FreeFlow設計中的主要挑戰。
3.1 總體設計
在原生RDMA中,如圖2(a)所示,應用程式利用RDMA API直接向硬體NIC發送命令,以實現控制和數據路徑功能。FreeFlow接收應用程式和物理網卡之間的通信,並在軟體FreeFlow路由器內執行控制平面和數據平面策略,該路由器作為主機上的另一個容器運行。特別的是,為了控制數據路徑,FreeFlo wrouter只允許物理NIC直接從自己的內存中讀取和寫入(圖2(b)中的虛擬內存),並負責將數據複製到應用程式的內存中。請注意,內部容器中的內存容器和FreeFlow router中的影子內存可以是零拷貝的同一塊物理內存(§4.3 )。
3.2 Verbs:RDMA的「窄腰」
有多種方法可以攔截應用程式和物理網卡之間的通信,但我們必須選擇有效的方法。 目前有許多支持RDMA的商業技術,包括Infiniband [9]、RoCE [8]和iWarp [19]。應用程式還可以使用幾種不同的高級API來訪問RDMA功能,例如MPI和rsocket [20]。如圖3所示,這些API事實上的「窄腰」是IB Verbs API(Verbs)。因此,我們有意識地選擇在FreeFlow中支持Verbs,這樣我們就可以自然地支持所有更高級別的API。
Verbs使用「隊列對」(QP)的概念進行數據傳輸。對於每個連接,兩個端點中的每一個都有一個sendqueue(SQ)和一個接收隊列(RQ),它們一起稱為QP。發送隊列保存有關需要發送的內存緩衝區的信息,而接收隊列保存有關接收傳入數據的緩衝區的信息。
每個端點還具有單獨的完成隊列(CQ),NIC使用該隊列來通知端點發送或接收請求的完成。Verbs庫和相關驅動程序允許讀取、寫入和監視三個隊列的應用程式。數據的實際傳輸,包括打包和錯誤恢復,由NIC處理。為了透明的支持Verbs ,FreeFlow創建虛擬NIC中的虛擬QP和CQ,以及將它們的操作與物理NI中的實際QP和CQ的操作聯繫起來。
3.3 FreeFlow 架構
FreeFlow的體系結構如圖4所示。我們修改或引入的容器網絡堆棧的三個組件以灰色顯示:(i)FreeFlow network library(FFL),(ii)FreeFlow software路由器(FFR),以及(iii)FreeFlow network orchestrator(FFO)。
FFL位於容器內部,是使FreeFlow對應用程式透明的關鍵。從應用程式的角度來看,它與標準的RDMA Verbs庫無法區分[16]。構建Verbs API的所有應用程式和中間件都可以在沒有(或可忽略的)修改的情況下運行,FF與FFR協作。
FFR在每個主機上運行單個實例,並與同一主機上的所有容器一起提供虛擬網絡。在數據平面中,FFR與同一主機上的容器共享內存緩衝區,並隔離不同容器的共享內存緩衝區。FFR通過NIC在共享內存中發送和接收數據,依靠FFL在應用程式的專用數據緩衝區和共享內存緩衝區之間同步數據。FFR通過控制容器和FFR之間的共享存儲器通道來實現數據平面資源策略,例如QoS。它還可以與FFO一起處理諸如IP位址分配之類的簿記任務。
FFO根據用戶定義的配置和集群的實時監控,為其集群中的所有容器做出控制平面決策。它還維護集中式存儲器映射,我們將在§4.3中討論。
3.4挑戰
在設計FreeFlow時,我們需要解決兩個關鍵挑戰。首先,FreeFlow應該提供一個RDMA接口,它透明地支持所有類型的現有RDMA操作。存在各種類型的RDMA操作,包括用於數據傳輸的單側和雙側操作,用於工作完成通知的輪詢和基於事件的機制,以及用於連接建立的TCP/IP和RDMA-CM。我們觀察到,由於RDMA操作的複雜性,透明地支持它們並不簡單。其次,FreeFlow應該提供接近裸機的RDMA性能,同時最小化CPU和內存開銷。由於FFR通過FFL接受來自應用程式的Verbs調用,所以我們需要仔細設計FFR和FFL之間的通信通道。我們將分別針對§4和§5中的每個挑戰提出我們的方法。
第四章 RDMA操作的支持
Verbs 支持多種操作和機制。使用WRITE/READ單方操作,讀取(寫入)方可以讀取(寫入)遠端伺服器特定內存地址的數據,而不需要事先通知對方。使用SEND/RECV雙方操作,發送方必須在接收方準備好接收數據之後才能發送數據。此外,程序也可以使用基於拉取或者基於事件的機制來處理任務完成通知。不同的程序根據自己的需要選擇不同的操作方式,我們發現在常用的應用程式中,這幾種操作都被使用到。[32、18、17、22]
FreeFlow完全透明地支持這些不同的RDMA操作。主要的挑戰是支持單方操作和基於事件的完成通知,因為,RDMA網卡會悄無聲息的修改FFR使用的內存或者文件描述符。FFR如果不持續的頻繁檢查內存或者文件描述符的話是不會馬上發現變更的,所以,及時的將物理網卡上的操作轉換到容器中的虛擬網卡上是非常困難的。但是,容器終歸是進程,FFL和FFR可以共享內存和文件描述符,藉助這個特點我們解決了這個問題,讓物理網卡所做的操作可以自動的傳入容器中。將應用程式的內存在FFL和FFR之間共享也不是很容易,因為,容器內的應用程式不會在IPC共享內存區申請內存,所以,我們需要將容器中的內存轉換成共享內存。
4.1 建立連接
兩個RDMA通信端首先需要建立連接。它們在各自的網卡上創建QP,並為QP申請一個內存緩存,然後與遠端的QP進行配對。當連接建立後,應用程式會要求NIC將本地緩存中的內容發送到遠端,或者將收到的內容放到本地緩存中。
圖5中的1~7步展示了使用Verbs創建連接的基本流程。左邊一列顯示了應用程式使用Verbs的順序。右邊陰影中的兩列展示了FreeFlow如何捕獲應用程中的Verbs調用,以及如何在發送端FFR和接受端之間建立連接。
第一步:應用程式查找支持Verbs的網卡。FFL截獲這個調用並返回容器的虛擬網卡。(即通知應用程式容器的虛擬網卡支持Verbs操作。)
第二步:應用程式在虛擬網卡上建立QP和CQ,同時FFR在物理網卡上創建對應的隊列(QP』和CQ』)。當FFR創建好這些隊列後,由FFL將QP-ID等隊列的元信息返回給應用程式。
第三步:應用程式註冊一塊內存(mem)到QP。FFR在自己的共享內存內部處理交互區(IPC)分配一塊同樣大小的內存(s-mem),並將其註冊到QP』上。FFR返回它創建的s-mem的ID,這個ID是主機上IPC內存區的唯一標示。FFL可以用這個ID將s-mem映射到自己的虛擬內存區中。
第四步:應用程式查詢本地QP的地址(在RDMA中叫GID)。這個地址信息會同時共享給本地和遠程的QP。最後,FFR返回QP』的真實GID。
第五步:應用程式與遠端交換GID和QP-ID。應用程式可以通過任何方式交換這些信息,例如TCP/IP,或RDMA-CM。
第六步:應用程式通過接收者的GID將本地的QP和遠端容器的QP配對。FFL將此GID轉發給FFR。FFR再用這個GID配對QP』。
第七步:應用程式將本地QP的狀態改為Ready,準備發送接收數據,同時FFR修改QP』的狀態。
第七步之後,從應用程式的角度來看,它已經可以發送或接收數據了– 它已經創建好了QP和CQ,在QP上註冊了mem,與遠端的QP建立了連接,並完成了與遠端QP的配對。
從FreeFlow的角度來看,它創建了與QP關聯的QP、與CQ關聯的CQ』,註冊了與mem關聯的s-mem,並且與遠端FFR中的QP』進行了配對。它也準備好接收並處理應用程式中的Verbs調用了。
由於FFR、FFL之間額外的交互,Freeflow可能會增加連接建立的延遲。但是它對總體延遲影響不大,因為建立連接是一次性行為;大部分的RDMA應用會重用之前建立好的連接。
4.2 雙方操作
在執行數據傳輸之前,發送者和接受者都需要進行兩步操作。第一步是用QP發送接收數據,第二步是用CQ來處理完成通知。圖5中的8、9步展示了這個過程。
第八步:應用程式執行SEND調用,並傳入了指向mem的指針。FFL首先複製mem中的數據到s-mem,然後FFR調用SEND指令,將s-mem中的數據發送到遠端的FFR。我們使用§4.3討論到的零複製機制來實現數據複製,而不是簡單的將數據從mem複製到s-mem。請注意,此時在遠端會觸發一個對應的RECV調用。
第九步:應用程式會通過檢測CQ或者等待通知來獲知send是否完成。同時FFR會檢測與CQ』並將結果發送給FFL。
對於同一個QP中的後續SEND操作,應用程式只需要重複第八、九步。RECV操作的工作流程除了第九步以外基本相同,FFL會在QP』接受完數據後將數據從s-mem複製到mem,就像SEND操作的第八步一樣。
對於應用程式來說,FFL和FFR是完全透明的。應用程式就像是在自己的虛擬網卡上執行一個普通Verbs操作。圖5展示的流程也是開發中使用Verbs的標準方法。這裡描述的FreeFlow的行為說明它可以完全支持SEND和RECV操作。
4.3 單方操作
在單方操作中,客戶端不止需要服務端的GID,同時還需要遠端內存緩存的地址,以及訪問內存所需的密鑰。這些信息會在圖5的第五步時進行交換,然後在第八步執行讀寫操作時使用。
與雙方操作相比,單方操作的透明支持更加有挑戰性。在FreeFlow中支持單方操作需要面臨兩個問題。
首先,目標存儲器地址mem位於遠程容器的虛擬存儲器中。但是,本地FFR不知道另一方的相應s-mem。例如,在圖6(a)中,當發送方試圖將mem-1中的數據寫入遠程存儲器mem-2時,它在階段3)就失敗了,因為接收器上的FFR無法訪問目標存儲器地址mem-2 。
為了解決這個問題,FreeFlow在FFO中為所有FFR構建了一個中心鍵值存儲,以保存應用程式虛擬內存空間中mem指針與FFR虛擬內存空間中相應s-mem指針之間的映射。當應用程式將內存註冊到其虛擬NIC時,更新此表會增加圖5中步驟3的延遲。但是,數據平面性能不會受到影響,因為FFR可以在本地緩存映射。
其次,即使我們知道遠程端的內存映射,WRITE和READ也可以遠程修改或複製數據而不通知遠程端的CPU,因此,FFR不知道何時複製到應用程式的存儲器或從應用程式的存儲器複製。例如,在圖6(b)中,發送方找到s-mem-2的正確地址並將數據發送給它。但是,在s-mem-2中有數據後,沒有通知接收器的FFR知道何時將s-mem-2複製到mem-2。解決此問題的一種方法是不斷同步s-mem-2和mem-2。 當然,這會消耗大量的CPU和內存總線帶寬。
為了解決這個問題,我們在FreeFlow中設計了一個基於零拷貝的機制來有效地支持單方操作。高級想法是使mem和s-mem具有相同的物理內存,因此FFR不需要進行任何複製,數據將自然地呈現給應用程式。圖6(c)說明了這種設計。通過刪除內存副本,我們還可以提高FreeFlow的性能。
這裡的關鍵是使應用程式直接分配和使用共享內存與FFR進行數據傳輸。為此,FreeFlow提供了兩個選項:選項1 - 創建新的API來分配共享內存:我們創建兩個新的Verbs函數,ibv _malloc和ibv_free,讓應用程式將內存創建和刪除委託給FreeFlow。這允許FFL直接在共享內存區域中分配這些緩衝區(與FFR共享),從而避免複製。這個選項的缺點是需要修改應用程式代碼,儘管修改應該只是數據緩衝區創建的幾行。選項2 - 將應用程式的虛擬內存地址重新映射到共享內存:當應用程式將虛擬內存地址va作為數據緩衝區註冊到私有內存塊時(例如,圖5中的步驟3),FFL釋放物理內存記憶片後面的va,並從FFR到va分配一個共享的物理內存片。在Linux中,此操作僅在va是內存頁面開頭的地址時有效。為了強制應用程式始終在頁面的開頭分配內存,FFL攔截C語言中的malloc之類的調用,並使其始終返回頁面對齊的內存地址。雖然此選項可以在不修改應用程式代碼的情況下實現零內存複製,但它會強制應用程式中的所有內存分配進行頁面對齊,這會導致主機上的內存效率降低。
在實踐中,我們建議使用第一個選項,因為它更清潔,更高效。但是,由於許多RDMA應用程式已經使它們的數據緩衝區頁面對齊以獲得更好的性能(例如,RDMA-Spark [18]),我們可以直接使用第二個選項而不攔截malloc,因此副作用有限。請注意,不管開發人員選擇使用選項1修改應用程式,還是應用程式本來就支持頁面對齊緩衝區,FreeFlow都不會在實際內存使用中產生任何開銷。
4.4 基於事件的操作
從CQs(完成隊列)中獲取信息有兩種方式。一種是讓應用定時檢查隊列中是否有結束的操作。另一種是基於事件的,由應用創建一個事件管道,然後將CQ加入管道。當有操作完成時可以通過管道中的文件描述符觸發相應的事件。
在FreeFlow中,由於原始文件描述符是由物理網卡創建的,FFR需要將文件描述符傳遞給FFL,否則後者無法感知與文件操作符相關的事件。但是FFL、FFR本質上共享同一個內核的兩個進程,藉助此特點也可以實現進程間文件描述符的傳遞,由此我們實現了將事件管道從FFR傳遞給了FFL。
參考文獻請查看原文連結,原文地址:
https://www.usenix.org/conference/nsdi19/presentation/kim
- 未完 -
由於章節眾多,我們將分多期進行刊登,敬請大家關注,謝謝。