看到Intel最近發布了QPI直連FPGA的架構,冬瓜哥回想起幾個月前寫的一篇文章,現在重新分享給大家。從中你可以了解為何需要FPGA,FPGA是怎么被連接到系統里的,怎么被使用的。
閑話少說,今天我們說一說IBM搞的CAPI,CAPI是OpenPower體系里的一個技術,其目的是讓FPGA更好更方便的融入現有的系統。那么現有的FPGA是怎么被使用的呢?不如先說說什么是FPGA,要弄清楚什么是FPGA,就得先說說什么是CPU。可笑,CPU大家都知道,冬瓜哥這逼格咋降低了?笑而不語。
·通用CPU是怎么運算的?
我們都知道所謂GPCPU(通用目的CPU),也就是什么都能算,但又什么都算不快的CPU,所以其“通用”,比如Intel x86,AMD x86,Power,PowerPC,MIPS,ARM,DragonSon/GodSon(國產)等。而FPGA就是專門為了某種某類計算而專門優化其內部的邏輯電路的一種專用CPU。GPCPU內部的ALU包含多種運算器比如加減乘除以及邏輯(比如xor,and,or,not)運算以及整數和浮點運算,我們開始菜單計算器,算加減法,代碼指令便會把對應的數據導入到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,每個時鐘周期只能將兩個64bit做XOR,如果我要XOR 兩份1GB的數據,就需要1GB/64bit=?(自己算)個時鐘周期,才能算完。此時,專用計算就派上用場了,也就是所謂的“硬加速”。總體來講硬加速有4種實現手段:露點、加寬、并行、直譯。露,就是直接把最終的運算單元給露出來,拋掉那些什么分支預測等流水線步驟;寬,就是把運算器位寬直接加大,一個周期多算一些數據;并就是把多種分支直接并行檢測,也就是把比較器/減法器直接并行化,結果相OR或者AND,來判斷后續路徑;直譯就是把多種條件直接用譯碼器做出來,一個周期輸出結果。所有這些都需要電路層面的改動,這就產生了FPGA現場可編程門電路陣列。FGPA內部就是一堆的直譯表(DRAM,用戶自己寫好邏輯然后輸入進去),再加上一些外圍接口,和一些固定的算法器件比如Flash控制器常用的LDPC硬核。NIC、存儲IO卡、防火墻、路由器等,內部都使用了應加速,比如網卡收到一個以太網幀,其需要解析幀頭,這種工作如果交給GPCPU的話,那就太慢了,來,先從內存讀入代碼看看要讓爺我干點啥?譯完了碼,來,進流水線等著吧,我順便去做個分支預判,找一找歷史預判數據,下一位!進了流水線后,親,你先排在后面吧因為你要的資源和別人有沖突。最后操作數到達ALU,尼瑪,就這么點位寬?小爺這噸位起碼得1Mbit位寬才放得下!親,下次再來吧,來之前先進閘刀給你閘成多個64bit,然后每次算64bit吧。。而硬加速直接把這個幀載入寄存器,其中電路直接導向各個譯碼器,直譯出下一步的操作,比如需要比對ALC,那么就多個目標地址/源地址并行比較一個周期輸出,這樣才能保證速度。
·專用FPGA怎么與系統對接?
目前的FPGA都是使用PCIE與host通信的,也就是做成一張PCIE卡查到主板PCIE槽上。主程序通過驅動程序,將需要運算的數據指針告訴FPGA,然后FPGA從主存DMA讀取待計算數據然后計算,算完后DMA回主存并通知主程序。
·多核心多CPU系統以及PCIE設備
所有CPU看到單一物理地址空間,所有Threads看到單一虛擬地址空間,PCIE物理地址空間映射到CPU物理地址空間,CPU物理地址空間也映射到PCIE物理地址空間。
數據出了ALU,面對的一張復雜的路由網絡,目的地址為內存地址,但是其相對外部網絡的復雜性在于,目標的位置是不固定的,還可能有多份拷貝。Need Coherency!硬件透明搞定Cache Coherency。CC不負責多線程并發訪問cache line時的互斥,互斥需要程序顯式發出lock,底層硬件會鎖住總線訪問周期。
·PCIE設備如何與CPU交互?
1.BusDriver將PCIE設備地址空間映射到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版本如何解決當前的問題?
AFU—Acceleration Function Unit,主加速邏輯部分,用戶寫入自己設計的邏輯和Firmware。
PSL—Power Service Layer, 提供接口給AFU用于讀寫主存和V2P地址翻譯(與CPU側使用同一個頁表,并包含TLB),同時負責Probe CAPP實現全局cc,并提供Cache。PSL由IBM作為硬核IP提供給FPGA開發者。
CAPP—Coherent Attached Processor Proxy, 相當于FPGA側的ccAgent,但是被放在了CPU側,其維護一個filter目錄并接受來自其他CPU的Probe,未過濾掉的Probe轉發PSL。
·性能能提高多少?
上圖是IBM自己的一個測試,利用CAPI enabled FC HBA(基于FGPA),與傳統方式相對比,性能提升非常大,我沒有是測過,對其底層的機制有點懷疑,FPGA后端同樣使用傳統的FC控制器以及驅動程序連接AFA陣列,這與直接把FC卡插在主機上相比,增加了一層CAPI,只會時延更高,但是結果卻是時延下降,由于IBM并沒有提供更多信息,所以這里不好判斷。
評論
查看更多