聊聊FPGA/GPCPU/PCIE/Cache-Coherency/CAPI1.0

聊聊FPGA/GPCPU/PCIE/Cache-Coherency/CAPI1.0

2015-05-28 冬瓜哥 大話存儲

640?wx_fmt=jpeg&tp=webp&wxfrom=5

冬瓜哥和存儲界的朋友們有個無聲的約定,那就是,想知道產品/技術背後的奧祕,瞭解底層,剝掉廠商包裝忽悠的外殼,那關注冬瓜哥是沒錯的,底層通,一通百通,逼格秒漲!冬瓜哥沒有太多精力和興趣去搜羅業界八卦並分析,聊八卦一向不是冬瓜哥的強項,雖然屬於MKT的角色,但是身在曹營心在漢,你和咱說市場,咱就和你論技術,忽悠死你,哈哈~~。冬瓜哥認爲,底層技術是終生受用的武器,冬瓜哥看任何產品或者說事物,都要看透其底層纔可罷休,否則冬瓜哥會感覺很不爽。

閒話少說,今天我們說一說IBM搞的CAPICAPIOpenPower體系裏的一個技術,其目的是讓FPGA更好更方便的融入現有的系統。那麼現有的FPGA是怎麼被使用的呢?不如先說說什麼是FPGA,要弄清楚什麼是FPGA,就得先說說什麼是CPU。可笑,CPU大家都知道,冬瓜哥這逼格咋降低了?笑而不語。

·        通用CPU是怎麼運算的?

我們都知道所謂GPCPU(通用目的CPU,也就是什麼都能算,但又什麼都算不快的CPU,所以其通用,比如Intel x86AMD x86PowerPowerPCMIPSARMDragonSon/GodSon(國產)等。而FPGA就是專門爲了某種某類計算而專門優化其內部的邏輯電路的一種專用CPUGPCPU內部的ALU包含多種運算器比如加減乘除以及邏輯(比如xorandornot)運算以及整數和浮點運算,我們開始菜單計算器,算加減法,代碼指令便會把對應的數據導入到CPU的寄存器,CPU收到之後便會將操作數輸入到運算器的輸入端,並在下一個時鐘週期獲取到計算結果並輸出到寄存器,然後寫回到主存。當然,GPCPU內部花費了大量的資源(邏輯電路)去做優化,包括緩存管理、流水線、多發射、分支預測、亂序執行等等,一條指令要最終得到執行,都要經過這些關卡的一層層處理,所以,對於那些遵紀守法的代碼(比如,順着來沒有任何判斷跳轉)來講其時延無疑會增加,但是目前隨着業務越來越複雜,應用程序的判斷條件越來越多,所以這些優化會增加最終性能,雖然時延相對上提高了,但是性能絕對上是增加了,因爲如果誤判了一個分支,那麼整個流水線已經預讀入的代碼就會被沖刷走重新讀入,這個時延反而會更大。

有人問了,我不打開計算器,就運行個QQ,難道還要算加減法麼?如果沒有什麼加減乘除運算,CPU運行QQ到底是運行了些什麼東西?這問題問得好,問的逼格高,一般人是根本不去想QQ運行時候底層都做了什麼的。其實GPCPU大多時候還真沒有在算加減乘除,而更多地是做協調工作了,也就是把內存裏某段數據讀出來,稍加改動或者根本不動,又寫到內存其他地方去。這不閒的麼,CPU就幹這個?是的。比如QQ要發送一句話給某個好友,其需要調用TCP協議棧頂上的soket API,後者就是一段常駐內存的OS內核代碼,那麼QQ.exe如何將這句話傳遞給這段代碼?QQ.exe會讓CPU把這句話在當前內存的地址告訴socket API代碼,其會將這個地址以及其他參數寫入到某個CPU寄存器,對應機器指令就是“mov 內存地址寄存器A”類似這種,然後QQ.exe調用socket API,對應機器指令就是“call socket API的內存地址CPU就會把QQ.exe當前的地址暫存起來以便後續返回繼續執行(這叫壓棧),然後再跳轉到socket API地址來執行socket代碼(從內存中該地址讀出socket代碼執行),socket代碼執行之後,會在CPU寄存器內發現之前傳遞過來的參數(要發送數據的內容等),然後按照這個參數向下調用TCP協議棧將數據打包,分段,貼上IP標籤,最後調用以太網卡驅動程序,調用過程與上述類似,然後發送到網卡。這個過程,在主路徑上,加減乘除運算並不是必須的,但是在輔路徑上,比如程序需要記住當前發送了多少內容了,TCP協議棧也要記錄當前發送了多少個分段了,這些就需要CPU做加法操作,來計數;另外,在遇到if代碼的時候,cpu會比對多個輸入條件,對應機器指令是comp(比較)以及jmpz/jmpnz(遇零跳轉/非零跳轉)等此時會用到減法器或者比較器,這恐怕是通用場景下用得最多的ALU運算器了。所以,上述這個過程,根本就不是一個大運算量的過程。但是你如果去聽mp3,解碼RMVB電影,那就需要大運算量了,這些場景也是專用場景。

·        專用FPGA又是怎麼計算的?

通用CPU做通用場景的代碼執行,很強,什麼都能幹,聽着歌聊着QQ做着ppt,再加上個SSD,體驗流暢的感覺。但是讓你算一算分子動力學,某個分子內的原子是怎麼運動的?算一算人臉識別?搞搞搜索?那通用CPU就歇菜了。此時,加減乘除、邏輯、整數、浮點統統一起上,通用場景下使用比例較少的這些ALU,但是專用場景下,這些ALU反而不夠用了,一個是數量太少,一個是位寬太低。比如XOR運算器,如果位寬只有64bit,每個時鐘週期只能將兩個64bitXOR,如果我要XOR 兩份1GB的數據,就需要1GB/64bit=?(自己算)個時鐘週期,才能算完。此時,專用計算就派上用場了,也就是所謂的硬加速總體來講硬加速有4種實現手段:露點、加寬、並行、直譯。露,就是直接把最終的運算單元給露出來,拋掉那些什麼分支預測等流水線步驟;寬,就是把運算器位寬直接加大,一個週期多算一些數據;並就是把多種分支直接並行檢測,也就是把比較器/減法器直接並行化,結果相OR或者AND,來判斷後續路徑;直譯就是把多種條件直接用譯碼器做出來,一個週期輸出結果。所有這些都需要電路層面的改動,這就產生了FPGA現場可編程門電路陣列FGPA內部就是一堆的直譯表(DRAM,用戶自己寫好邏輯然後輸入進去),再加上一些外圍接口,和一些固定的算法器件比如Flash控制器常用的LDPC硬核。NIC、存儲IO卡、防火牆、路由器等,內部都使用了應加速,比如網卡收到一個以太網幀,其需要解析幀頭,這種工作如果交給GPCPU的話,那就太慢了,來,先從內存讀入代碼看看要讓爺我乾點啥?譯完了碼,來,進流水線等着吧,我順便去做個分支預判,找一找歷史預判數據,下一位!進了流水線後,親,你先排在後面吧因爲你要的資源和別人有衝突。最後操作數到達ALU,尼瑪,就這麼點位寬?小爺這噸位起碼得1Mbit位寬才放得下!親,下次再來吧,來之前先進閘刀給你閘成多個64bit,然後每次算64bit吧。。而硬加速直接把這個幀載入寄存器,其中電路直接導向各個譯碼器,直譯出下一步的操作,比如需要比對ALC,那麼就多個目標地址/源地址並行比較一個週期輸出,這樣才能保證速度。

·        專用FPGA怎麼與系統對接?

目前的FPGA都是使用PCIEhost通信的,也就是做成一張PCIE卡查到主板PCIE槽上。主程序通過驅動程序,將需要運算的數據指針告訴FPGA,然後FPGA從主存DMA讀取待計算數據然後計算,算完後DMA回主存並通知主程序。

·        多核心多CPU系統以及PCIE設備

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy

所有CPU看到單一物理地址空間,所有Threads看到單一虛擬地址空間,PCIE物理地址空間映射到CPU物理地址空間,CPU物理地址空間也映射到PCIE物理地址空間。

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy

數據出了ALU,面對的一張複雜的路由網絡,目的地址爲內存地址,但是其相對外部網絡的複雜性在於,目標的位置是不固定的,還可能有多份拷貝。Need Coherency!硬件透明搞定Cache CoherencyCC不負責多線程併發訪問cache line時的互斥,互斥需要程序顯式發出lock,底層硬件會鎖住總線訪問週期。

·        PCIE設備如何與CPU交互?

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy

1.   BusDriverPCIE設備地址空間映射到CPU物理地址空間並將PCIE地址空間寫入PCIE設備寄存器。

2.   HostDriver讀出PCIE設備寄存器獲取該設備對應的PCIE物理地址空間並ioremap()到內核虛擬地址空間

3.   HostDriver 申請DMA緩存並向PCIE設備映射的虛擬地址空間寫入控制字、基地址等,這些信息便被寫入設備寄存器,從而觸發PCIE設備根據基地址從主存DMA拿到需要的指令和數據後進行處理。

4.   PCIE設備對主存DMA時,RC自動執行Probe操作以保證CacheCoherency

·        當前交互方式存在的不足

1.   執行路徑長而且全軟件參與:應用call->傳輸協議棧(如有)->Host驅動->PCIE設備->DMAà中斷服務->Host驅動->傳輸協議棧(如有)->應用buffer

2.   PCIE設備與CPU看到不同的物理地址空間,RC進行映射和轉換。驅動程序申請內存之後得用pci_map_single()映射成PCIE物理地址。

3.   用戶態程序必須主動從內核地址空間mmap()纔可以直接與PCIE設備DMA互傳數據。用戶態程序必須區分不同的地址段。

·        CAPI1.0版本如何解決當前的問題?

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy

AFU—Acceleration Function Unit,主加速邏輯部分,用戶寫入自己設計的邏輯和Firmware

PSL—Power Service Layer, 提供接口給AFU用於讀寫主存和V2P地址翻譯(與CPU側使用同一個頁表,幷包含TLB),同時負責Probe CAPP實現全局cc,並提供CachePSLIBM作爲硬核IP提供給FPGA開發者。

CAPP—Coherent Attached Processor Proxy, 相當於FPGA側的ccAgent,但是被放在了CPU側,其維護一個filter目錄並接受來自其他CPUProbe,未過濾掉的Probe轉發PSL

·        性能能提高多少?

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy

上圖是IBM自己的一個測試,利用CAPI enabled FC HBA(基於FGPA),與傳統方式相對比,性能提升非常大,我沒有是測過,對其底層的機制有點懷疑,FPGA後端同樣使用傳統的FC控制器以及驅動程序連接AFA陣列,這與直接把FC卡插在主機上相比,增加了一層CAPI,只會時延更高,但是結果卻是時延下降,由於IBM並沒有提供更多信息,所以這裏不好判斷。

·        CAPI1.0暫時做不到的事情,Maybe in future

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy

o    CPU側看不到AFU上的地址空間(MMIO控制寄存器地址除外)

o    AFU只能給一個進程使用:進程Open AFU之後便獨佔之。

o    如果可以把FPGA直接接入CPUFSB,是不是會更快?Maybe in future


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章