石 偉,龔 銳,劉 威,王 蕾,馮權友,張劍鋒
(國防科技大學計算機學院,湖南 長沙 410073)
隨著摩爾定律[1]的發展,單芯片上計算資源不斷增加,I/O帶寬與速率相對于高性能芯片計算性能的差距不斷增大。如何提升處理器的I/O性能一直是高性能處理器設計及高性能計算機系統面臨的重要問題[2]。隨著云計算、AI、大數據和數據密集型計算的發展,I/O的性能問題更加突出[3,4]。
從功能角度,處理器的高性能I/O接口可以分為存儲、通信和加速接口等幾類。針對數據密集型的科學計算,應用程序在運行過程中需要讀寫的數據量達到TB甚至PB級[4],這些數據需要通過I/O接口存入外部大容量磁盤等存儲設備。針對超級計算機系統,各計算結點之間通常通過InfiniBand、以太網和OPA(Omni-Path Architecture)等接口進行互連[5]。隨著加速器技術的發展,AI和GPGPU等加速模塊通過PCIe[6]、CXL[7]和NVlink[8]等接口連接到處理器上。此外,對于高性能服務器,服務器芯片通過直連接口進行通信,比如CCIX[9]和UPI(Ultra Path Interconnect)[10]等。實際上,很多高性能處理器都實現了上述幾種類型I/O高速接口,比如IBM的POWER9[11]、華為鯤鵬920和Intel 至強處理器[10]。
針對I/O的瓶頸問題,主要存在2類解決方法:第1類是從系統級進行優化。文獻[12,13]通過優化系統軟件或并行I/O庫的方法提升I/O接口的使用效率,提升性能。文獻[3,14]從應用的角度分析I/O行為及I/O效率低下的原因,進而進行有針對性的優化。第2類方法是對處理器接口直接進行優化設計,如提升接口的傳輸速率,實現更多的通道數或優化控制器的傳輸延遲。以PCIe協議為例,隨著協議不斷進化,目前主流的PCIe 3.0傳輸速率達到了8 Gbps,具有16 Gbps傳輸速率的PCIe 4.0已經成功應用于一些高性能處理器中[11,15]。PCIe 5.0速率達到了32 Gbps,IBM最新發布的POWER10處理器采用了該協議[16]。為了提升帶寬,高性能處理器通常設計實現32~80個PCIe通道,最高帶寬達到了320 GB/s。此外,高性能服務器芯片通常還可能同時實現CCIX、以太網、USB和SATA等高速接口。
對一個高性能處理器來說,通過提升I/O接口的帶寬與速率能夠直接提升I/O的性能,但是處理器設計是一個系統級的工程,并不是簡單的集成。集成數量眾多且帶寬超高的I/O接口對處理器的片上網絡NoC(Network on Chip)設計提出了巨大挑戰。本文對處理器內的片上網絡進行優化設計,以匹配高帶寬I/O接口。由于I/O接口與片上網絡協議的差異性與復雜性,往往會導致死鎖現象的產生,從而增加系統設計難度,甚至對系統性能產生負面影響。本文針對死鎖問題,提出一種高效解決方法。該方法無需通過增加各種約束條件來防止死鎖的產生,而是在死鎖產生后,通過死鎖檢測、死鎖撤銷及事務恢復的方法重新激活網絡中的事務。
圖1為微處理器結構示意,其中處理器簇、PCIe接口、直連接口和DMA設備等通過Cache一致性網絡進行互連,通過監聽等手段保證各主設備看到相同的數據視圖。Cache一致性網絡同時還負責地址譯碼與報文路由的功能,將請求轉發到內存空間或I/O空間。I/O網絡則負責將I/O請求進一步轉發到不同外設。DMA設備可以是一些專門加速模塊,比如密碼引擎等。網絡接口可以直接設計在處理器內部,也可以通過PCIe接口進行協議轉換。加速器接口根據加速器的接口協議,可以采用不同的實現方式,在處理器內部實現專用加速接口,或直接連接在PCIe上,或復用PCIe部分邏輯來實現。

Figure 1 Interconnection network in processors圖1 處理器互連網絡結構示意
圖1給出了處理器上各設備進行數據交換的基本結構,但是具體如何進行數據交換還需要網絡協議支持。傳統的互連協議有IBM公司的CoreConnect、ARM公司的AMBA(Advanced Microcontroller Bus Architecture)、Silicore公司的Wishbone和OCP-IP (Open Core Protocol International Partnership)設計的OCP協議等。隨著處理器復雜度的不斷增加,互連由傳統的總線向片上網絡演變,片上通信由片上報文完成[17]。不同的網絡協議在具體實現方面差別較大,可以從事務類型、并發度、物理及邏輯通道對應關系、維序方式和死鎖防護等方面對網絡協議進行比較分析。

Figure 2 Three kinds of write operation processes圖2 3種寫操作流程示意
事務類型是一個網絡協議的基礎,一般包括Cache一致性事務、DMA事務和I/O事務等。PCIe等外設采用的DMA操作主要包括DMA讀與DMA寫。DMA寫將數據寫入內存,DMA讀從內存中讀出數據并傳輸給外設。DMA讀寫通常會涉及Cache一致性處理,但本文主要側重讀寫性能優化,因此不對Cache一致性處理進行描述。在不同處理器或架構中,事務的具體實現方式也不盡相同。圖2給出了3種寫事務的具體實現流程。在圖2a中,發送方首先向接收方發出請求報文;接收方如果可以接收寫數據,會向發送方發送報文可接收的通知;發送方接收到通知后,則向接收方發出數據;最后接收方通知發送方寫操作完成。ARM公司的CHI(Coherent Hub Interface)協議與圖2a類似[18]。在圖2b中,數據跟隨請求直接發出,如ARM公司的AXI(Advanced eXtensible Interface)協議[19]。在圖2c中,請求與數據通過一個報文發送,如UltraSPARC T2的報文傳輸方式[20]。
并發度與協議的性能直接相關。并發度高的協議可以以流水方式發出請求,然后以流水方式接收響應,比如ARM公司的AXI協議。而并發度低的協議,事務是串行完成的,比如APB(Advanced Peripheral Bus)協議。在延遲大的網絡中,只有以流水方式處理多個事務,才能達到較高性能。
一個事務通常由幾個不同功能的報文組成,這些報文可以獨占一個物理通道或者共享一個物理通道。AXI協議的讀請求與寫請求分別獨占一個通道,而CHI協議的讀請求與寫請求則共享一個請求通道。
在處理器中,很多事務之間是存在順序性要求的。比如PCIe協議要求不同事務之間必須保證一定的順序,否則無法保證協議正確性[6]。AXI協議通過事務編號來保證事務順序完成,而CHI協議通過報文域來指定順序性,并且通過特定的硬件實現來保證順序。在進行協議轉換的時候,需要保證事務之間的順序性被正確轉換。
死鎖也是協議經常需要面對的問題,每一種協議都需要設置一定的規則來避免產生死鎖。對于很多復雜網絡協議,必須保證網絡通路不被堵死。一般情況下,可以通過重發與信用機制來保證網絡不被堵死。當接收方收到發送方的報文時,如果接收方不能處理,則可以通過重發機制通知發送方進行重發,而不是一直將其堵在接收方的入口,進而阻塞其他報文的接收。信用機制則是發送方在知道接收方肯定能夠接收報文的情況下將報文發送出去。接收方如果能夠繼續接收報文,則通過信用釋放的方式通知發送方。

Figure 3 Interconnection between PCIe and DDR圖3 PCIe與DDR交互示意
以PCIe與DDR(Double Data Rate)存儲器為例,兩者之間通常需要進行多種協議轉換、時鐘域轉換和位寬轉換等,如圖3所示。如果PCIe與DDR采用通用IP(Intellectual Property),則其接口一般會采用標準的AXI協議。PCIe控制器與DDR控制器需要分別將PCIe協議、DDR協議與AXI協議進行轉換。在不同架構中,NoC網絡通常也有自己的特定協議,因此需要將AXI協議與網絡協議進行轉換。圖3中DCU(Directory Control Unit)為目錄控制單元,負責Cache一致性管理。
以16 通道PCIe 4.0為例,其讀寫峰值帶寬需求分別為32 GB/s。在圖3所示的整個通路上,需要以峰值帶寬為設計目標,確保各部分的帶寬不存在瓶頸。在Cache一致性網絡中,每次讀寫的報文最大粒度是固定的,稱為Cache行,其大小為Bcacheline。讀寫帶寬的計算方式如式(1)所示,與讀寫并發個數Ot和源結點到目的結點的網絡延遲t有關。在時間t內完成的并發讀寫數目越多,讀寫總帶寬越大。
(1)
雖然通過提升讀寫并發數能夠提升帶寬,但是能夠設計實現的讀寫并發數是有限制的,如式(2)所示:
(2)
其中,Ntransfer表示傳輸每個Cache行數據報文所需的時鐘周期數,Omax表示實現的最大并發數,f表示電路時鐘頻率。當電路中設計實現的實際并發數超過Omax以后,將有部分讀寫操作無法流水執行。如果非要提升系統的Omax,可以通過降低Cache行傳輸時鐘周期來實現。另外,通過減小網絡傳輸延時t,可以在使用更小并發數的同時獲得相同的網絡帶寬,從而節省邏輯資源。
在圖3中,PCIe控制器距離內存最遠,因此讀寫并發數要求最大。而DDR控制器距離內存最近,設計較小的并發數就能獲得同等的傳輸帶寬。對于低頻率的電路,可以通過提高數據位寬來獲得與高頻率電路相等的帶寬。
在互連網絡中,死鎖是一個必須解決的問題。死鎖是指2個或2個以上的網絡結點在事務執行過程中,由于資源競爭導致多個事務相互依賴,無法完成,網絡處于永久阻塞狀態。為防止死鎖,設計人員提出了各種死鎖避免機制,比如采用信用、重發機制、防死鎖路由等技術確保網絡暢通,然而這些機制只是初級的死鎖避免策略。在很多情況下,死鎖與通信結點的特點、微結構設計還存在較大相關性。在進行微結構設計的時候,需要充分考慮通信結點的特點,優化設計,避免死鎖。
PCIe協議的posted類型的寫事務具有強序要求[6],所有的posted類型的寫必須順序完成,即處理器看到這些數據的次序必須與PCIe寫入的次序相同。最簡單的實現方式是串行實現,但是實現效率低,事務不能流水執行。AXI協議通過采用相同的編號來實現維序[19],CHI協議通過順序發送Compack來進行維序[18]。
在具體實現時,不同的微結構往往會導致不同的死鎖場景出現。圖4給出了一種死鎖場景,實現了AXI協議與NoC報文協議的轉換。AXI發出3個DMA寫請求,其中前面2個寫請求被重發,第3個寫地址C的請求先進入DCU流水線,并且對地址C的讀請求先于重發的請求進入FIFO(First Input First Output)。此時死鎖依賴關系形成,WriteC依賴于 WriteA與WriteB,WriteA與WriteB依賴于ReadC,而ReadC因為地址沖突依賴于WriteC。對于這種死鎖,可以通過修改微架構來解鎖,比如分開處理讀事務與寫事務,或者保證寫請求順序進入DCU流水線。

Figure 4 An implementation related deadlock scenario圖4 一種基于特定實現的死鎖場景示意
除了上述可以通過修改微架構避免的死鎖,微處理器系統中還可能存在一些無法避免的死鎖,如圖5所示。多個PCIe結點向多個DCU結點發送寫請求,地址分別為A與B。PCIe0先發出寫A地址的請求,后發出寫B地址的請求,且要求寫A地址先于寫B地址完成。PCIe1的行為則正好相反。A地址在DCU0中處理,B地址在DCU1中處理。在DCU0中,PCIe1的請求先處理,PCIe0的請求由于地址沖突,處于等待狀態。在DCU1中,PCIe0的請求先處理,PCIe1的請求由于地址沖突,處于等待狀態。經過分析,可以看到形成一個如圖5所示的首尾相連的依賴圖,出現了死鎖。對于這種死鎖,無法通過修改微結構來避免,但是可以通過修改事務處理機制來解決死鎖,使后續操作能夠恢復執行。

Figure 5 Deadlock dependency between PCIe and DCU圖5 PCIe與DCU的死鎖依賴關系
鑒于第4節所述的死鎖無法避免的情況,本節首先設計實現一種高性能協議轉換模塊,負責將PCIe-AXI協議轉換為NoC網絡協議,如圖6所示;然后重點闡述死鎖檢測及死鎖撤銷機制的設計與實現。

Figure 6 Conversion module of PCIe and NoC protocol圖6 PCIe與NoC協議轉換模塊
轉換模塊分為讀處理模塊與寫處理模塊,讀處理模塊與寫處理模塊相對獨立,但是共享NoC通道。DCU模塊需要進行配合設計,防止死鎖產生。讀請求通道與寫請求通道都支持重發功能,報文存儲在內部的重發緩沖中,事務完成后才被撤銷。讀寫請求分別支持128與64個并發請求,以獲得與16通道PCIe 4.0相匹配的帶寬。
對于不可避免的死鎖,首先檢測其發生;然后通過特殊方法打破死鎖依賴關系,將死鎖事務撤銷;最后將撤銷的事務重新恢復并執行。圖7給出了死鎖處理狀態機。在工作/檢測模式狀態下,檢測邏輯一直監聽模塊的接口與內部狀態。如果模塊中有未完成的事務,且接口及內部狀態在一段時間內處于不變狀態,即可認為可能發生了死鎖。本文通過一個16位寄存器表示最大檢測時間,且軟件可配置。當檢測計數器達到最大檢測時間時,觸發進入撤銷模式。死鎖撤銷保存現場,以特殊方式完成目前未完成的事務,同時保證特殊完成的事務不影響系統狀態,效果上是將目前的事務撤銷。在死鎖解除以后,死鎖處理狀態機進入恢復模式,將之前撤銷的請求恢復進入流水線,繼續執行。

Figure 7 Deadlock handling state machine圖7 死鎖處理狀態機
在通常情況下,寫操作發出寫請求給DCU模塊,DCU如果可以接收數據,則向I/O模塊返回數據可接收標志,然后I/O模塊將數據發送給DCU模塊。為了能夠對數據進行撤銷,數據的發送需要依照請求發送次序進行,否則可能導致后續數據先于前面數據寫入,導致前面數據無法進行撤銷。
圖8為死鎖撤銷處理示意圖。請求發出以后,進入寫數據Index FIFO,等待數據接收通知。如果FIFO頭部的請求接收到寫數據可接收的通知,則發出該請求對應的數據。正常情況下,請求的Index按照先進先出方式處理,后面的請求不能超越前面的請求,這也是死鎖依賴關系中的一環。進入死鎖撤銷階段,寫數據Index FIFO自動移位,接收到數據接收通知的請求移到FIFO頭部,并發送空數據給DCU模塊,DCU接收到空數據操作后,不會將數據寫入內存,相當于將當前的寫操作撤銷。FIFO中其他請求在接收到數據接收通知后都進行寫空數據操作。

Figure 8 Process of deadlock release圖8 死鎖撤銷處理示意圖
由于是2個PCIe模塊的請求產生死鎖,可以在一個轉換模塊中進行報文撤銷,從而將死鎖依賴環中的一個依賴關系打破,進而解除死鎖。
在寫操作被撤銷以后,這些請求必須重新恢復并重新執行,圖9為報文恢復示意圖。由于存在重發機制,請求結點中的重發緩沖將所有未完成的請求信息都記錄下來,只需要增加一個取消報文Index FIFO。一個請求進入轉換模塊以后,會同時進入取消報文Index FIFO,當請求完成以后,將對應請求的Index從Index FIFO彈出。因此,取消報文Index FIFO中的請求實際上是當前未完成的請求,也是撤銷階段被撤銷的報文。進入報文恢復階段,將取消報文Index FIFO中的數據寫入請求報文Index FIFO;同時再次寫入取消報文Index FIFO,防止這些請求再次產生死鎖。

Figure 9 Process of message recovery圖9 報文恢復處理示意圖
為驗證本文設計方法的有效性,在服務器芯片中對上述方法進行了實現,主要功能包括報文切分與協議轉換。報文切分模塊將PCIe發出的AXI報文切割成Cache行大小的報文,協議轉換將基于Cache行的AXI報文轉換成基于NoC的網絡報文。本文共實現了3個版本,版本1的讀寫并發個數分別為64與32,版本2的讀寫并發個數分別為128和64,版本3在版本2的基礎上增加了死鎖檢測與撤銷的功能。3個版本設計的頻率均能達到2.5 GHz以上,面積比較如表1所示。實驗結果表明,面積增加主要是由讀寫并發數增加導致的,而死鎖檢測及撤銷對面積影響不大。

表1 3種版本面積比較(單元數)Table 1 Area comparison(Cell counts)
基于版本3對死鎖檢測與死鎖撤銷功能進行測試,如圖10所示。圖10中共出現了4次死鎖及死鎖處理。死鎖產生以后,死鎖檢測計數器計數到最大值,然后進入死鎖撤銷狀態。死鎖撤銷過程中,轉換模塊與DCU之間進行交互,寫入無效數據。死鎖撤銷以后,死鎖恢復操作將取消的請求恢復到流水線繼續執行。

Figure 10 Flow of message processing圖10 報文處理流程圖
本節對版本1與版本3的性能進行了測試。版本1的讀寫帶寬均達到17 GB/s左右,而版本3的讀寫帶寬均達到30 GB/s左右。圖11給出了版本3 DMA讀帶寬示意圖,可以看出DMA讀數據基本處于滿負荷狀態傳輸。對性能進一步分析,在相同的環境下,讀寫并發個數與網絡帶寬成正比;此外,版本3的128個讀并發數與64個寫并發數存在稍微過剩的問題。但是在實際系統中,由于訪存延遲的不確定性與訪存沖突的存在,DMA延遲可能增大,讀寫并發數目稍大一些有利于DMA性能的穩定性。

Figure 11 DMA read bandwidth without address conflict圖11 無地址沖突情況下DMA讀帶寬示意
對2個PCIe同時進行DMA讀寫測試,在地址無沖突請求下,每個16通道 PCIe 4.0的DMA讀寫帶寬基本達到28 GB/s~29 GB/s,滿足設計需求,同時表明整個DMA通路上不存在系統瓶頸。如果PCIe讀寫之間、PCIe與PCIe之間、PCIe與CPU之間訪問相同地址,系統沖突增加,DMA帶寬將受到一定的影響。圖12給出一種存在沖突情況下的DMA讀寫帶寬示意,總體帶寬約為21 GB/s。從圖12中可以看出,在數據沖突較多的情況下,數據通道的利用率較低,帶寬也有所降低;在數據沖突較少的情況下,數據通道的利用率逐漸增大,帶寬能夠提升至30 GB/s。

Figure 12 DMA read and write bandwidth with address conflict圖12 地址沖突情況下DMA讀寫帶寬示意
本文針對高性能處理器I/O帶寬受限問題,研究了片上網絡優化技術,給出了一種高帶寬片上網絡設計指導方法,以更好地匹配不斷增加的I/O種類及I/O帶寬。針對復雜網絡存在死鎖的問題,提出一種死鎖檢測及死鎖解除的方法,有效提升了系統的魯棒性。采用死鎖解除的方法能夠最大限度地減少網絡設計及運行時的約束,提升I/O性能。最后,基于高性能處理器對提出的方法進行驗證,實驗結果表明,本文提出的網絡優化方法能夠有效地提升I/O性能。本文的研究成果能夠應用到更復雜或I/O性能要求更高的其他高性能處理器中,具有較為廣泛的應用前景。