在考慮今天如何開始時,我回顧了一下這兩天關于硬件和軟件之間分歧的主題演講。主要探討了擁塞控制如何在這個不斷發展的領域中增長和演變。由于技術不斷變革,問題也不斷涌現,因此解決方案需要隨時間調整。此外,ChatGPT的普及和加速器的進步正在從根本上改變通信模式,以及通信的負載和要求。因此,我想確保大家了解這是我們真正要討論的重點。接下來的講話將專注于該領域的一個具體方面。
有一些問題,我知道你們中的一些人之前已經遇到過。為什么你會再次提出這個問題?為什么你要對比RDMA和TCP?實際上,RoCE和IB已經很好地滿足了大多數高性能通信需求。然而,還有很多工作要做,特別是關于啟用亂序傳輸(Out-of-order delivery)和選擇性確認(Selective Acknowledgements, SACK),以提高自由傳輸的效率。我們期望實現比現有方案更好的性能,其中擁塞控制機制是一個關鍵。今天早些時候,我們也討論了一些類似的增強功能。這個領域非常值得關注,因為不同的工作負載和流程對擁塞控制方案有不同的要求。因此,這也是RoCE持續發展和改進的方向。
另外,當我們從圍繞RDMA構建的特殊定制網絡轉向使應用程序更具通用性時,流量將將成為更加關鍵的因素。對于TCP的熟悉程度,以及在規模上調試問題的經驗,理解如何處理問題、如何分配帶寬、如何確保公平性等,這些都是TCP帶來的挑戰,并迫使我們重新思考和審視這些問題。
最后一個觀點是,雖然RoCE通常運行在定制的后端網絡或特定目的構建網絡上,但構建一個完整的生態系統還需要考慮通用存儲的需求。之前的討論提到了云服務,這些服務幾乎總是在某種TCP變體上運行。隨著機器學習的不斷增長,特別是推理服務在云路徑上的應用,這些服務并不總是依賴于定制網絡。盡管如此,它們仍然面臨巨大的數據和帶寬需求。
因此,問題在于TCP是否存在根本性問題,是否需要徹底改進,或者我們能否重新利用它。在這個領域,觀點各異,有些人認為TCP對于數據中心來說并不適用,我們需要從頭開始設計。Homa就是這樣一個例子。但讓我們深入探討一下,看看我們能為TCP做些什么。
那么,為什么要關注TCP呢?在數據中心網絡的領域中,擁塞控制算法的豐富性無疑是最為關鍵的一環。這是一個歷經數十年深入研究的領域,提供了眾多行為模型供我們選擇,使得我們可以根據具體用例挑選最合適的模型。無論你是在尋找適用于短距離數據中心鏈路的方案,還是適用于遠距離廣域網鏈路的方案,甚至是混合鏈路的解決方案,都有相應的選項可供選擇。這個領域內的擁塞控制、速率控制、公平性等概念易于理解,同時選擇性確認和高效重傳等機制也得到了廣泛的研究。此外,預測性支持亂序包交付和有序完成的能力也是系統設計中不可或缺的一部分。
一個值得探討的問題是:這不是之前已經嘗試過了嗎?顯然,iWARP就是其中一次較大的嘗試。在這次嘗試中,人們試圖將RDMA框架概念置于TCP基本傳輸方案之上。但這一嘗試至少需要依賴硬件TCP引擎來實現,這實際上排除了很多可能性。你必須選擇你能實現的東西,無論是固件還是硬件,最終基本上限制了TCP可用的速率、速度和靈活性。此外,在網絡上執行TCP以及在RDMA與主機之間進行框架轉換的嘗試,使得該協議變得異常復雜且難以實現。
另一個嘗試是名為OpenOnload或Onload的堆棧。該堆棧實際上將TCP庫置于用戶空間,并引導路徑,以避免TCP執行受到應用程序線程的鎖定爭用,而是在應用程序的上下文中執行庫。Solarflare的解決方案在高頻交易(HFT)和高性能計算(HPC)領域取得了巨大成功,我相信這里的人們都有所了解。然而,它也面臨著同樣的問題。多年來,它已經偏離了可以稱為標準TCP的東西,即Linux實現。這導致Linux堆棧經歷的一些增強和改進在該模型中無法使用。隨著時間的推移,它成為了一個分歧的解決方案,引發了一些額外的摩擦。
接下來是DPDK標準的經典用戶空間TCP實現,這種實現經常在中間件中使用。它在電信解決方案中非常受歡迎,因為它試圖以最小的CPU開銷和最少的符合性或兼容性要求來執行TCP。然而,我認為它有些過于專業化,并不常見作為一種通用的廣泛部署的解決方案。
因此,我們仍然面臨一個問題:是否能讓TCP在簡單硬件上易于實現,并達到所需的性能水平。
那么,多年來TCP發展受阻的原因是什么呢?套接字,對吧。我想在這方面不會有太多問題。同步的、基于系統調用的套接字接口存在問題,它與現代異步、低開銷的標準接收器模型不符。然而,由于安裝基數如此之大,實際上在短期內廢除套接字是不值得實現的方案。
然而,在消息傳遞方面,我們確實面臨著一系列挑戰。一種常見的訪問模式,在TCP上實現它卻是相當困難的。特別是在字節流序列上構建消息框架,這本身就是一個棘手的問題。如果我們要支持無序的消息傳遞,那么難度將會進一步增加。雖然在高層次上有成功的例子,如NVMe-TCP,但這并不意味著這是一個簡單的任務。你需要投入大量的工作來從字節流中提取PDU流,并確保每個層次都能獨立且正確地工作。這意味著在效率和性能方面,我們需要付出相當大的努力。實際上,我們之前的討論也提到了,你需要在某個暫存緩沖區中進行PDU分割,然后再進行DM處理。
傳統上,TCP并不支持零拷貝技術,但稍后我們會看到關于零拷貝影響的相關數據。最新的Linux實現在發送(Tx)方面已經具備了相當不錯的零拷貝功能,但在接收(Rx)方面仍存在一些問題。盡管Tx的實現很棒,且真正實現了零拷貝,但其效率仍無法與RDMA和寫操作相比。關于內核頁面翻轉機制,一個關鍵問題是,除非CPU完全控制與實際頁表相關的異構內存,否則它可能無法正常工作。這些頁表可能位于PCI交換機中,并不受主機內存管理單元(MMU)的控制。
最后,TCP面臨的一個挑戰是精確放置和管理緩沖區。顯然,你可以解鎖一個緩沖區,并通過TCP套接字接口進行讀寫操作。但如果你希望進行更具體的操作,那么你不希望受到套接字緩沖區(SKB)的開銷影響,也不希望從無法控制的內存空間分配任何額外數據。實現對應用程序的透明處理是相當困難的。因此,這些是我認為TCP存在的不足之處。
在接下來的演講中,我們將探討是否能解決這些問題,并討論一個具體的實現方案。我們一直在努力嘗試解決這些問題,并希望最終能夠取得成功的結果。
我們目前正在參與的測試或生態系統,展示在左邊的這張圖片中。這是一塊標準的Ryzen主板,上面插入了一張FPGA卡。這張FPGA卡上又連接了兩個GPU。這張FPGA卡的功能類似于一個網絡路由器和一個PCIe交換機,其PCI通道均為Gen 3 x16,以太網端口為100G。盡管速度是一個重要的考慮因素,但在這個設計中,從GPU出來的路徑實際上并未達到100G的能力,而只能運行在大約40G。因此,我們不會過多地討論這個路徑的細節。
這個特定的FPGA設置,我們可以將其視為在Enfabrica中實際構建的設計的硬件近似。它支持一些令人印象深刻的功能。其中之一是它能夠進行完整的硬件分類和轉向。這意味著它可以一直查看到L5頭。一旦它在L4級別識別出特定的流,特別是如果它知道了一個流是什么,它就可以跟蹤在該流內部看到的字節偏移量。此外,它還實現了一個相當高效的TSO/GRO方案(幻燈片中的信息有誤)。
讓我們先來看一些數據,然后再深入探討其實際含義。右邊的圖表展示了我們所利用硬件驅動所能實現的性能。很明顯,我們無法達到800G的速率。因此,在這個實驗中,我們基本上從數據包中移除了所有有效載荷字節,使其僅在頭部模式下運行。我們盡可能地提高應用程序和堆棧的運行速度,使用的是未經修改的Linux內核,上面運行著我們的驅動程序。我們的目標是測量在各種MTU數據包下,我們可以實現多快的數據包速率和有效吞吐量。吞吐量是通過將分組數乘以空包大小來計算的。
從圖表中可以明顯看出,沒有GRO的情況下性能相當差。使用軟件GRO相比基準性能有了明顯的提升,但仍然相對較低。然而,當我們使用我們的硬件GRO方案和修改后的驅動程序時,開銷大大降低,我們實際上可以接近達到800G的數據包速率。為了實現這一目標,我們需要覆蓋非常廣泛的MTU范圍,并且在較低的MTU大小下,我們的速率增長也相當可觀。因此,實際上,我們可以只運行所需速度的堆棧。
這意味著,我們學到或之前推測的其中一點是,套接字API接口存在相當大的問題。它幾乎增加了所有的開銷,并影響了驅動程序實現和資源效率。具體來說,套接字API接口沒有在關鍵路徑中進行緩存分配,而是選擇在非關鍵路徑中進行。然而,值得注意的是,原生的SACK和ACK操作實際上運行得非常好。它們能夠保持相當穩定的速率,并且確實從無序數據和有序完成模型中受益。因此,在出現輕微故障時,它們能夠非常無縫地恢復,而不會引發真正的問題,前提是故障和重傳發生在某個特定的窗口內。
另一件要考慮的事情是,如果我們仔細審視Linux堆棧本身,它已經成為最令人滿意的堆棧之一。每個月都有大約五到十個提交,其中一到兩個通常是具有顯著性能優勢的重要更新。此外,Linux堆棧擁有一個龐大的社區,這個社區非常活躍,持續關注著性能及其影響。
在擁塞控制算法方面,已經有了巨大的改進。像BBR這樣的新算法在關鍵地方產生了重要影響。短隊列的實現使得緩沖區膨脹不再成為問題,即使在使用TSO/GRO類型方案時也是如此。此外,無縫路由對于鏈路負載和鏈路(或分布數據)的問題至關重要。
特別是在機器學習和大數據類型應用的背景下,這一點變得更加重要。想象一下,如果你有200G的鏈路,但在短時間內所有流量都集中在其中一個鏈路上,那么你就會遇到問題,整體效率會急劇下降。
值得一提的是,使用eBPF作為可配置攔截器是一種非常有效和有趣的動態擁塞控制機制。此外,Big TCP也是一個解決方案,它實際上應該在之前提到過的某個地方被提及。TCP在有效負載大小方面并沒有做得很好,而Big TCP通過超過16位有效負載大小的限制,允許主機表達比16位更大的緩沖區。
這個圖表沒有展示的是CPU利用率,這顯然是一個關鍵問題,與其他堆棧一樣重要。其中一個待解決的問題是,為了達到所需的性能水平,需要多少CPU資源。今天,我們將探討其中的一些問題,但對于真正感興趣的人,我建議關注這兩個鏈接。在我們發布幻燈片時,這兩個鏈接應該會出現在其中。David在這兩次演講中詳細闡述了我們對某些研究的看法,以及這些小改變如何影響CPU利用率,并影響我們達到高數據包速率的能力。
我們確實研究過像io_uring和af_xdp這樣的解決方案。io_uring顯然具有很多潛力,它擁有許多吸引人的特性,為你提供了人們期望的異步直接訪問接口。然而,這是一個新的API,將其融入現有的堆棧中,如機器學習,需要時間。也許將來會實現。零拷貝RX路徑仍在開發中,需要付出大量努力才能有效地實現零拷貝RX并獲得所需的結果。
我們在一定程度上研究了af_xdp,但基本上跳過了它。因為XDP的主要目標是將數據包快速送入用戶空間,而協議棧仍然是一個待解決的問題。因此,它更接近我之前提到的DPDK解決方案。但實際上,你并沒有獲得一個經過良好測試、可互操作且高效運行的堆棧。
那么,我們構建了什么呢?我們構建的方式看起來像右側這張相當復雜的圖片。從這張圖表中可以看出,大部分元素都是Linux堆棧中已有的部分,我們基本上沒有進行大的修改,只是進行了一些細微的調整。核心的部分是我們所稱的核心設備驅動程序,它負責驅動隊列、進行維護工作,以及執行所有必要的操作。我們在堆棧中添加了一個非常標準的InfiniBand提供者和驅動程序庫或驅動程序層。
這張圖表應該與你所見過的其他圖表非常相似。你的工作區域在用戶空間,有工作隊列和完成隊列用于發送和接收工作,你還有一個提交密鑰,可以直接將緩沖區發布到硬件上。這里最獨特的地方在于這兩個箭頭。實際上,我們在側通路上收集散射列表,并將其提交到內核中的TCP堆棧,使其驅動網絡驅動程序推送傳輸數據包或讀取請求數據包。
在接收路徑上,當數據包到達時,我們執行完全相同的操作。當一個數據包到達時,我們通過這個庫或這個堆棧,然后將數據放入接收隊列中。而且,數據實際上將要到達的緩沖區的內存區域已經為硬件所準備,因此數據直接落在緩沖區所在的內存區域。
因此,這實際上是一種混合體,與你在現有框架中看到的TCP實現有所不同。但有趣的是,這張圖表中的每一個元素都是真實存在的,我們只是對Linux堆棧中現有的方案和組件進行了重新組合和重新連接。
那么在我們的系統上實際運行起來是怎樣的效果呢?我們采用的模型與之前的描述是一致的。現在,你的機器學習應用程序通過NIC與一個IB Verb堆棧進行通信,工作隊列、發送和接收隊列都對這個應用程序開放。應用程序通過驅動程序將這些操作傳輸到在CPU上運行的內核實現。有效載荷就位于這里,稍后你會看到我們提供的數據,對比了它在GPU內存區域和CPU內存區域之間的表現。正如之前所提到的,提交隊列直接接入硬件,發送和接收工作請求通過內核驅動程序進行傳遞,并轉換為我們的硬件隊列格式,然后進行相應的處理。
值得一提的是,數據路徑,特別是這個調用進入TCP/IP堆棧的部分,避開了近年來內核堆棧中大量的功能性增加。我們可以稱之為“功能性增加”,即人們一直在使用和添加的各種鉤子,用于劫持或接管數據移動。我們繞過了所有這些,對調用的內核函數進行了非常精心的選擇。事實上,Linux堆棧始終建立在回調式設計的基礎上,因此許多事情可以被隔離并單獨調用,而不是從套接字的頂部一直到底部,以及反之亦然地獲取整個數據包。
雖然這個模塊顯示的是TCP,但另一個值得注意的地方是,這個模塊可以是任何東西。我們今天不會深入討論這一點,但我們所討論的結構模型允許我們用RXE替換這個模塊。RXE是Linux內核中的一個RoCE實現。在接下來的討論中,大部分內容將保持不變。
我們之前討論過的一個問題是,在TCP字節流上放置消息時的無能或低效性。為了解決這一問題,過去的主要方法是使用iWARP,它位于RDMA堆棧的頂部。通過RDMA over DDP over MPA方案,在TCP的頂部構建了RDMA堆棧,以便在正確位置獲得標記,并實現零拷貝的直接數據放置。
另一個選擇,我指的是,這是一個L5協議,需要構建相當復雜的硬件。而我們正在添加或已實現的是這個概念:通過TCP進行消息傳遞。我們的方法是在TCP頭部添加一個小的選項頭,我稱之為“BTH-like”,它就像一個信息頭,包含了BTH的所有內容。假設它位于標準RoCE數據包中BTH標頭所在的位置,它允許我們建立消息與隊列之間的關聯,以及確定傳遞消息的位置。特別地,它攜帶了兩個信息字段:一個告訴我們操作的階段,我們采用RoCE操作碼;另一個告訴我們這個特定字節集合屬于哪個消息,以及哪個字節偏移對應于該消息的起始位置。
這個方案類似于MPA或MPF標頭解決的問題,但它允許我們的硬件根據消息序列獲取緩沖區,除了字節序列外,還能正確處理消息,避免在消息疊加在字節流上時的混淆。這使我們相信這是一種更好的方法來解決問題,而不是iWARP。因為它使硬件保持簡單,允許基本的TCP正常工作。當這個標頭出現時,我們可以增強其功能并做一些更復雜的事情,而由此產生的效率提升是相當明顯的。
然而,這種方法的一個缺點是我們目前將其添加為TCP選項頭,這意味著中間設備可能無法正確處理。但對于我們當前關注的數據中心用例,我們認為這不是問題。如果人們希望與我們合作,將其納入類似規范和標準的東西,以便中間設備可以配合,我們將非常感興趣。
如果沒有數據支持,談話就失去了意義。在這里,我為你提供一些相關數據。在查看圖表之前,我想先說明一下,我們展示的基準系統正是我們正在介紹的FPGA系統。如果你僅在此系統上運行TCP和iPerf,我們得到的延遲是幾百微秒。但令人驚訝的是,這個系統能夠以4K MTU或4K消息大小的速度達到每秒三百萬個數據包,足以填滿100G的帶寬。
基于這個背景,我們再來仔細看看這些圖表。左邊的圖表對比了我們與標準的RoCE。我想那應該是Mellanox CX-5,展示的是CPU到CPU或CPU到GPU之間的傳輸情況。這是針對熟悉GPU直通技術的人,其目的緩沖區來自GPU內存。你可以看到,延遲顯然沒有達到生產中基于硬件的實現水平。這主要有兩個原因:一方面,我們在軟件方面還有很多工作要做以提高效率;但另一方面,硬件運行的時鐘頻率只有我們所需的四分之一,并且缺乏許多優化。因此,在達到目標之前,我們的很多事務實際上需要多個DMA周期。
然而,我認為仍然值得驕傲的是,當你開始查看4K和16K的數字時,你會發現我們的延遲在這些范圍內仍然相當平穩和穩定,而這在運行標準TCP時是無法看到的。在吞吐量方面,也許更有趣。同樣,如果你注意到,在4K的表現上,我們確實比RoCE NIC差得多。這同樣是目前軟件和調優的問題,因為我們知道在運行標準TCP時我們可以達到100G的數值,所以這實際上是我們IB堆棧上的一個問題。
但更令人振奮的是,我們成功地掌握了曲線,達到了吞吐量。如果你看看4、16、64K大小的數據包,這是大部分機器學習工作重點關注的地方,我們的堆棧表現非常出色。另外,我應該指出的是,我們傳遞給GPU的數據,由于其再次通過我們的解決方案,與其他解決方案相比,其延遲稍微低一些。
最后一個圖表將展示我們在這里要強調的關鍵點。通過我們所做的工作,有效地將堆棧與應用程序的其余部分以及服務這些操作的內存(在我們的案例中為GPU)隔離開來。你會發現,這實際上會帶來更好的TCP性能。讓我為你解釋一下。
紅色和藍色的圖表再次展示了標準的CPU到CPU和CPU到GPU操作。而黃色和青色的圖表則揭示了當存在內存訪問競爭者時,這兩條曲線會發生什么變化。為了模擬這種情況,我們在系統上運行了stress-ng,并在后臺最大限度地增加了DRAM的訪問量。你會看到,CPU到CPU路徑開始出現問題,有時甚至會產生嚴重的性能下降。而CPU到GPU路徑則能夠保持其性能,因為GPU存儲控制器并沒有受到stress-ng的太大影響。盡管藍色和黃色的曲線略有偏移,但它們的峰值仍然保持在預期的位置。
因此,這個隔離模型不僅有效,而且實際上解決了一些性能問題,特別是與TCP性能要求相關的問題。
總之,通過讓操作系統讓步,將RDMA應用作為Linux TCP堆棧之上的應用程序接口,你將能夠看到性能上的顯著提升。
-----
可以支持RDMA讀寫流,那么可以支持的最大消息大小是多少?
是的,我們確實支持RDMA讀寫流。關于您提到的最大消息大小,我們的BTH頭部策略中包含一個OP code,這使得我們可以在硬件中靈活地處理不同的處理上下文或其他RDMA操作。目前,我們在該頭部設定了一個24位消息大小,這一設計選擇是基于實現上的多種因素考慮,旨在達到一個性能與復雜性的平衡。即使在處理高達800G和TB級的消息吞吐量時,這一設計也不會成為性能瓶頸。同時,在重試或類似操作中,它也不會增加太多復雜性。
還有一些限制,也就是我們硬件的這種FPGA近似,有些事情我們的設備做得更好。
來自Peter Gotzman的問題,關于Lipsy控制路徑加IB verbs數據路徑,應用程序是否需要采取特殊步驟來分配和固定緩沖區,我很好奇應用程序需要改變多少。
對于RDMA應用程序來說,它們可以正常工作,無需進行其他更改。但如果你打算嘗試某種應用程序級的混合操作,我建議你使用RDMA機制進行注冊,然后按你的需要進行。
Bernard的問題,你是否了解過軟件iWARP?它很好地印證了你對于PDU傳遞復雜性的觀點,然而,當采用分段卸載的方式時,它的性能表現得相當出色。
是的,這與我們的觀察結果相吻合。以NVMe-TCP為例,我們投入了大量時間去研究其內在含義。在實際操作中,我們可以協助硬件進行分段和分段信號的處理。然而,這些上層類型方案的問題在于,最壞情況下的性能可能會非常糟糕。尤其是當在PDU邊界上進行重傳時,而這部分操作已經完成并跨越了多條消息。
實際上,有人提出這個問題,我感到很高興。因為我也想在這方面發表一些看法。你的觀點是正確的。確實存在處理基于PDU的協議的方法,但其中存在一個基本的區別。那就是,如果你需要查看TCP流以找到PDU邊界,那么你需要全面查看TCP的完整負載。這將更加昂貴,并且不太適合無狀態的卸載。相比之下,如果數據包邊界與消息邊界對齊,那么處理起來會更加高效。
這意味著,由于你能夠獲得數據包邊界,因此你只需要在數據包傳輸過程中簡單地處理其頭部信息。而有效負載部分可以更接近零拷貝,正如Shrijeet所提到的,這些數據可以直接發送到GPU或類似設備進行處理。
還有一個問題來自Sean,關于RDMA的后續問題。在該頭部中沒有RKEY。
是的,我們在那里并沒有放置完整的結構。在RoCE中,RKEY并不位于BTH中,而是位于BTH后的擴展頭部中。所以,我們的處理方式其實是類似的。如果TCP BTH中的OP code表示后面有一個用于RDMA操作的擴展頭部,那么你會在那里查找任何內存鍵或其他內容。我們目前還沒有深入研究原子操作,但理論上來說,這也是可行的。當然,我并不想過于預測未來,但理論上,你可以在那里放置一個原子擴展頭部,或者任何與RoCE和InfiniBand類似的內容。
至于我想說的,Sean,我們正在尋求關于這個頭部需要什么的參與或合作。另外,你關于層次結構的具體問題,我認為,引發了我們應該放置什么以及是否放置過多的問題。這可能會導致TCPE選項頭部存在大小限制和擴展的含義。
審核編輯:劉清
-
加速器
+關注
關注
2文章
796瀏覽量
37838 -
Linux
+關注
關注
87文章
11292瀏覽量
209326 -
TCP
+關注
關注
8文章
1353瀏覽量
79055 -
RDMA
+關注
關注
0文章
77瀏覽量
8945 -
ChatGPT
+關注
關注
29文章
1558瀏覽量
7595
原文標題:技術講座:RDMA和Linux TCP
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論