看到Intel最近發(fā)布了QPI直連FPGA的架構(gòu),冬瓜哥回想起幾個月前寫的一篇文章,現(xiàn)在重新分享給大家。從中你可以了解為何需要FPGA,F(xiàn)PGA是怎么被連接到系統(tǒng)里的,怎么被使用的。
閑話少說,今天我們說一說IBM搞的CAPI,CAPI是OpenPower體系里的一個技術(shù),其目的是讓FPGA更好更方便的融入現(xiàn)有的系統(tǒng)。那么現(xiàn)有的FPGA是怎么被使用的呢?不如先說說什么是FPGA,要弄清楚什么是FPGA,就得先說說什么是CPU??尚?,CPU大家都知道,冬瓜哥這逼格咋降低了?笑而不語。
·通用CPU是怎么運算的?
我們都知道所謂GPCPU(通用目的CPU),也就是什么都能算,但又什么都算不快的CPU,所以其“通用”,比如Intel x86,AMD x86,Power,PowerPC,MIPS,ARM,DragonSon/GodSon(國產(chǎn))等。而FPGA就是專門為了某種某類計算而專門優(yōu)化其內(nèi)部的邏輯電路的一種專用CPU。GPCPU內(nèi)部的ALU包含多種運算器比如加減乘除以及邏輯(比如xor,and,or,not)運算以及整數(shù)和浮點運算,我們開始菜單計算器,算加減法,代碼指令便會把對應(yīng)的數(shù)據(jù)導(dǎo)入到CPU的寄存器,CPU收到之后便會將操作數(shù)輸入到運算器的輸入端,并在下一個時鐘周期獲取到計算結(jié)果并輸出到寄存器,然后寫回到主存。當(dāng)然,GPCPU內(nèi)部花費了大量的資源(邏輯電路)去做優(yōu)化,包括緩存管理、流水線、多發(fā)射、分支預(yù)測、亂序執(zhí)行等等,一條指令要最終得到執(zhí)行,都要經(jīng)過這些關(guān)卡的一層層處理,所以,對于那些遵紀守法的代碼(比如,順著來沒有任何判斷跳轉(zhuǎn))來講其時延無疑會增加,但是目前隨著業(yè)務(wù)越來越復(fù)雜,應(yīng)用程序的判斷條件越來越多,所以這些優(yōu)化會增加最終性能,雖然時延相對上提高了,但是性能絕對上是增加了,因為如果誤判了一個分支,那么整個流水線已經(jīng)預(yù)讀入的代碼就會被沖刷走重新讀入,這個時延反而會更大。
有人問了,我不打開計算器,就運行個QQ,難道還要算加減法么?如果沒有什么加減乘除運算,CPU運行QQ到底是運行了些什么東西?這問題問得好,問的逼格高,一般人是根本不去想QQ運行時候底層都做了什么的。其實GPCPU大多時候還真沒有在算加減乘除,而更多地是做協(xié)調(diào)工作了,也就是把內(nèi)存里某段數(shù)據(jù)讀出來,稍加改動或者根本不動,又寫到內(nèi)存其他地方去。這不閑的么,CPU就干這個?是的。比如QQ要發(fā)送一句話給某個好友,其需要調(diào)用TCP協(xié)議棧頂上的soket API,后者就是一段常駐內(nèi)存的OS內(nèi)核代碼,那么QQ.exe如何將這句話傳遞給這段代碼?QQ.exe會讓CPU把這句話在當(dāng)前內(nèi)存的地址告訴socket API代碼,其會將這個地址以及其他參數(shù)寫入到某個CPU寄存器,對應(yīng)機器指令就是“mov 內(nèi)存地址寄存器A”類似這種,然后QQ.exe調(diào)用socket API,對應(yīng)機器指令就是“call socket API的內(nèi)存地址”,CPU就會把QQ.exe當(dāng)前的地址暫存起來以便后續(xù)返回繼續(xù)執(zhí)行(這叫壓棧),然后再跳轉(zhuǎn)到socket API地址來執(zhí)行socket代碼(從內(nèi)存中該地址讀出socket代碼執(zhí)行),socket代碼執(zhí)行之后,會在CPU寄存器內(nèi)發(fā)現(xiàn)之前傳遞過來的參數(shù)(要發(fā)送數(shù)據(jù)的內(nèi)容等),然后按照這個參數(shù)向下調(diào)用TCP協(xié)議棧將數(shù)據(jù)打包,分段,貼上IP標(biāo)簽,最后調(diào)用以太網(wǎng)卡驅(qū)動程序,調(diào)用過程與上述類似,然后發(fā)送到網(wǎng)卡。這個過程,在主路徑上,加減乘除運算并不是必須的,但是在輔路徑上,比如程序需要記住當(dāng)前發(fā)送了多少內(nèi)容了,TCP協(xié)議棧也要記錄當(dāng)前發(fā)送了多少個分段了,這些就需要CPU做加法操作,來計數(shù);另外,在遇到if代碼的時候,cpu會比對多個輸入條件,對應(yīng)機器指令是comp(比較)以及jmpz/jmpnz(遇零跳轉(zhuǎn)/非零跳轉(zhuǎn))等此時會用到減法器或者比較器,這恐怕是通用場景下用得最多的ALU運算器了。所以,上述這個過程,根本就不是一個大運算量的過程。但是你如果去聽mp3,解碼RMVB電影,那就需要大運算量了,這些場景也是專用場景。
·專用FPGA又是怎么計算的?
通用CPU做通用場景的代碼執(zhí)行,很強,什么都能干,聽著歌聊著QQ做著ppt,再加上個SSD,體驗流暢的感覺。但是讓你算一算分子動力學(xué),某個分子內(nèi)的原子是怎么運動的?算一算人臉識別?搞搞搜索?那通用CPU就歇菜了。此時,加減乘除、邏輯、整數(shù)、浮點統(tǒng)統(tǒng)一起上,通用場景下使用比例較少的這些ALU,但是專用場景下,這些ALU反而不夠用了,一個是數(shù)量太少,一個是位寬太低。比如XOR運算器,如果位寬只有64bit,每個時鐘周期只能將兩個64bit做XOR,如果我要XOR 兩份1GB的數(shù)據(jù),就需要1GB/64bit=?(自己算)個時鐘周期,才能算完。此時,專用計算就派上用場了,也就是所謂的“硬加速”。總體來講硬加速有4種實現(xiàn)手段:露點、加寬、并行、直譯。露,就是直接把最終的運算單元給露出來,拋掉那些什么分支預(yù)測等流水線步驟;寬,就是把運算器位寬直接加大,一個周期多算一些數(shù)據(jù);并就是把多種分支直接并行檢測,也就是把比較器/減法器直接并行化,結(jié)果相OR或者AND,來判斷后續(xù)路徑;直譯就是把多種條件直接用譯碼器做出來,一個周期輸出結(jié)果。所有這些都需要電路層面的改動,這就產(chǎn)生了FPGA現(xiàn)場可編程門電路陣列。FGPA內(nèi)部就是一堆的直譯表(DRAM,用戶自己寫好邏輯然后輸入進去),再加上一些外圍接口,和一些固定的算法器件比如Flash控制器常用的LDPC硬核。NIC、存儲IO卡、防火墻、路由器等,內(nèi)部都使用了應(yīng)加速,比如網(wǎng)卡收到一個以太網(wǎng)幀,其需要解析幀頭,這種工作如果交給GPCPU的話,那就太慢了,來,先從內(nèi)存讀入代碼看看要讓爺我干點啥?譯完了碼,來,進流水線等著吧,我順便去做個分支預(yù)判,找一找歷史預(yù)判數(shù)據(jù),下一位!進了流水線后,親,你先排在后面吧因為你要的資源和別人有沖突。最后操作數(shù)到達ALU,尼瑪,就這么點位寬?小爺這噸位起碼得1Mbit位寬才放得下!親,下次再來吧,來之前先進閘刀給你閘成多個64bit,然后每次算64bit吧。。而硬加速直接把這個幀載入寄存器,其中電路直接導(dǎo)向各個譯碼器,直譯出下一步的操作,比如需要比對ALC,那么就多個目標(biāo)地址/源地址并行比較一個周期輸出,這樣才能保證速度。
·專用FPGA怎么與系統(tǒng)對接?
目前的FPGA都是使用PCIE與host通信的,也就是做成一張PCIE卡查到主板PCIE槽上。主程序通過驅(qū)動程序,將需要運算的數(shù)據(jù)指針告訴FPGA,然后FPGA從主存DMA讀取待計算數(shù)據(jù)然后計算,算完后DMA回主存并通知主程序。
·多核心多CPU系統(tǒng)以及PCIE設(shè)備
所有CPU看到單一物理地址空間,所有Threads看到單一虛擬地址空間,PCIE物理地址空間映射到CPU物理地址空間,CPU物理地址空間也映射到PCIE物理地址空間。
數(shù)據(jù)出了ALU,面對的一張復(fù)雜的路由網(wǎng)絡(luò),目的地址為內(nèi)存地址,但是其相對外部網(wǎng)絡(luò)的復(fù)雜性在于,目標(biāo)的位置是不固定的,還可能有多份拷貝。Need Coherency!硬件透明搞定Cache Coherency。CC不負責(zé)多線程并發(fā)訪問cache line時的互斥,互斥需要程序顯式發(fā)出lock,底層硬件會鎖住總線訪問周期。
·PCIE設(shè)備如何與CPU交互?
1.BusDriver將PCIE設(shè)備地址空間映射到CPU物理地址空間并將PCIE地址空間寫入PCIE設(shè)備寄存器。
2.HostDriver讀出PCIE設(shè)備寄存器獲取該設(shè)備對應(yīng)的PCIE物理地址空間并ioremap()到內(nèi)核虛擬地址空間
3.HostDriver 申請DMA緩存并向PCIE設(shè)備映射的虛擬地址空間寫入控制字、基地址等,這些信息便被寫入設(shè)備寄存器,從而觸發(fā)PCIE設(shè)備根據(jù)基地址從主存DMA拿到需要的指令和數(shù)據(jù)后進行處理。
4.PCIE設(shè)備對主存DMA時,RC自動執(zhí)行Probe操作以保證CacheCoherency
·當(dāng)前交互方式存在的不足
1.執(zhí)行路徑長而且全軟件參與:應(yīng)用call-》傳輸協(xié)議棧(如有)-》Host驅(qū)動-》PCIE設(shè)備-》DMAà中斷服務(wù)-》Host驅(qū)動-》傳輸協(xié)議棧(如有)-》應(yīng)用buffer
2.PCIE設(shè)備與CPU看到不同的物理地址空間,RC進行映射和轉(zhuǎn)換。驅(qū)動程序申請內(nèi)存之后得用pci_map_single()映射成PCIE物理地址。
3.用戶態(tài)程序必須主動從內(nèi)核地址空間mmap()才可以直接與PCIE設(shè)備DMA互傳數(shù)據(jù)。用戶態(tài)程序必須區(qū)分不同的地址段。
·CAPI1.0版本如何解決當(dāng)前的問題?
AFU—Acceleration Function Unit,主加速邏輯部分,用戶寫入自己設(shè)計的邏輯和Firmware。
PSL—Power Service Layer, 提供接口給AFU用于讀寫主存和V2P地址翻譯(與CPU側(cè)使用同一個頁表,并包含TLB),同時負責(zé)Probe CAPP實現(xiàn)全局cc,并提供Cache。PSL由IBM作為硬核IP提供給FPGA開發(fā)者。
CAPP—Coherent Attached Processor Proxy, 相當(dāng)于FPGA側(cè)的ccAgent,但是被放在了CPU側(cè),其維護一個filter目錄并接受來自其他CPU的Probe,未過濾掉的Probe轉(zhuǎn)發(fā)PSL。
·性能能提高多少?
上圖是IBM自己的一個測試,利用CAPI enabled FC HBA(基于FGPA),與傳統(tǒng)方式相對比,性能提升非常大,我沒有是測過,對其底層的機制有點懷疑,F(xiàn)PGA后端同樣使用傳統(tǒng)的FC控制器以及驅(qū)動程序連接AFA陣列,這與直接把FC卡插在主機上相比,增加了一層CAPI,只會時延更高,但是結(jié)果卻是時延下降,由于IBM并沒有提供更多信息,所以這里不好判斷。
評論
查看更多