眾所周知,通用處理器(CPU)的摩爾定律已入暮年,而機(jī)器學(xué)習(xí)和 Web 服務(wù)的規(guī)模卻在指數(shù)級(jí)增長。人們使用定制硬件來加速常見的計(jì)算任務(wù),然而日新月異的行業(yè)又要求這些定制的硬件可被重新編程來執(zhí)行新類型的計(jì)算任務(wù)。FPGA (Field Programmable Gate Array) 正是一種硬件可重構(gòu)的體系結(jié)構(gòu),常年來被用作專用芯片(ASIC)的小批量替代品,然而近年來在微軟、百度等公司的數(shù)據(jù)中心大規(guī)模部署,以同時(shí)提供強(qiáng)大的計(jì)算能力和足夠的靈活性。
不同體系結(jié)構(gòu)性能和靈活性的比較
FPGA 為什么快?「都是同行襯托得好」。CPU、GPU 都屬于馮·諾依曼結(jié)構(gòu),指令譯碼執(zhí)行、共享內(nèi)存。FPGA 之所以比 CPU 甚至 GPU 能效高,本質(zhì)上是無指令、無需共享內(nèi)存的體系結(jié)構(gòu)帶來的福利。
馮氏結(jié)構(gòu)中,由于執(zhí)行單元(如 CPU 核)可能執(zhí)行任意指令,就需要有指令存儲(chǔ)器、譯碼器、各種指令的運(yùn)算器、分支跳轉(zhuǎn)處理邏輯。由于指令流的控制邏輯復(fù)雜,不可能有太多條獨(dú)立的指令流,因此 GPU 使用 SIMD(單指令流多數(shù)據(jù)流)來讓多個(gè)執(zhí)行單元以同樣的步調(diào)處理不同的數(shù)據(jù),CPU 也支持 SIMD 指令。而 FPGA 每個(gè)邏輯單元的功能在重編程(燒寫)時(shí)就已經(jīng)確定,不需要指令。
馮氏結(jié)構(gòu)中使用內(nèi)存有兩種作用。一是保存狀態(tài),二是在執(zhí)行單元間通信。由于內(nèi)存是共享的,就需要做訪問仲裁;為了利用訪問局部性,每個(gè)執(zhí)行單元有一個(gè)私有的緩存,這就要維持執(zhí)行部件間緩存的一致性。對(duì)于保存狀態(tài)的需求,F(xiàn)PGA中的寄存器和片上內(nèi)存(BRAM)是屬于各自的控制邏輯的,無需不必要的仲裁和緩存。對(duì)于通信的需求,F(xiàn)PGA每個(gè)邏輯單元與周圍邏輯單元的連接在重編程(燒寫)時(shí)就已經(jīng)確定,并不需要通過共享內(nèi)存來通信。
說了這么多三千英尺高度的話,F(xiàn)PGA 實(shí)際的表現(xiàn)如何呢?我們分別來看計(jì)算密集型任務(wù)和通信密集型任務(wù)。
計(jì)算密集型任務(wù)的例子包括矩陣運(yùn)算、圖像處理、機(jī)器學(xué)習(xí)、壓縮、非對(duì)稱加密、必應(yīng)搜索的排序等。這類任務(wù)一般是 CPU 把任務(wù)卸載(offload)給 FPGA 去執(zhí)行。對(duì)這類任務(wù),目前我們正在用的 Altera(似乎應(yīng)該叫 Intel 了,我還是習(xí)慣叫 Altera……)Stratix V FPGA 的整數(shù)乘法運(yùn)算性能與 20 核的 CPU 基本相當(dāng),浮點(diǎn)乘法運(yùn)算性能與 8 核的 CPU 基本相當(dāng),而比 GPU 低一個(gè)數(shù)量級(jí)。我們即將用上的下一代 FPGA,Stratix 10,將配備更多的乘法器和硬件浮點(diǎn)運(yùn)算部件,從而理論上可達(dá)到與現(xiàn)在的頂級(jí) GPU 計(jì)算卡旗鼓相當(dāng)?shù)挠?jì)算能力。
FPGA 的整數(shù)乘法運(yùn)算能力(估計(jì))
FPGA 的浮點(diǎn)乘法運(yùn)算能力(估計(jì))
在數(shù)據(jù)中心,F(xiàn)PGA 相比 GPU 的核心優(yōu)勢(shì)在于延遲。像必應(yīng)搜索排序這樣的任務(wù),要盡可能快地返回搜索結(jié)果,就需要盡可能降低每一步的延遲。如果使用 GPU 來加速,要想充分利用 GPU 的計(jì)算能力,batch size 就不能太小,延遲將高達(dá)毫秒量級(jí)。使用 FPGA 來加速的話,只需要微秒級(jí)的 PCIe 延遲(我們現(xiàn)在的 FPGA 是作為一塊 PCIe 加速卡)。未來 Intel 推出通過 QPI 連接的 Xeon + FPGA 之后,CPU 和 FPGA 之間的延遲更可以降到 100 納秒以下,跟訪問主存沒什么區(qū)別了。
FPGA 為什么比 GPU 的延遲低這么多?這本質(zhì)上是體系結(jié)構(gòu)的區(qū)別。FPGA 同時(shí)擁有流水線并行和數(shù)據(jù)并行,而 GPU 幾乎只有數(shù)據(jù)并行(流水線深度受限)。例如處理一個(gè)數(shù)據(jù)包有 10 個(gè)步驟,F(xiàn)PGA 可以搭建一個(gè) 10 級(jí)流水線,流水線的不同級(jí)在處理不同的數(shù)據(jù)包,每個(gè)數(shù)據(jù)包流經(jīng) 10 級(jí)之后處理完成。每處理完成一個(gè)數(shù)據(jù)包,就能馬上輸出。而 GPU 的數(shù)據(jù)并行方法是做 10 個(gè)計(jì)算單元,每個(gè)計(jì)算單元也在處理不同的數(shù)據(jù)包,然而所有的計(jì)算單元必須按照統(tǒng)一的步調(diào),做相同的事情(SIMD,Single Instruction Multiple Data)。這就要求 10 個(gè)數(shù)據(jù)包必須一起輸入、一起輸出,輸入輸出的延遲增加了。當(dāng)任務(wù)是逐個(gè)而非成批到達(dá)的時(shí)候,流水線并行比數(shù)據(jù)并行可實(shí)現(xiàn)更低的延遲。因此對(duì)流式計(jì)算的任務(wù),F(xiàn)PGA 比 GPU 天生有延遲方面的優(yōu)勢(shì)。
計(jì)算密集型任務(wù),CPU、GPU、FPGA、ASIC 的數(shù)量級(jí)比較(以 16 位整數(shù)乘法為例)
ASIC 專用芯片在吞吐量、延遲和功耗三方面都無可指摘,但微軟并沒有采用,我認(rèn)為出于兩個(gè)原因:
1.數(shù)據(jù)中心的計(jì)算任務(wù)是靈活多變的,而 ASIC 研發(fā)成本高、周期長。好不容易大規(guī)模部署了一批某種神經(jīng)網(wǎng)絡(luò)的加速卡,結(jié)果另一種神經(jīng)網(wǎng)絡(luò)更火了,錢就白費(fèi)了。FPGA 只需要幾百毫秒就可以更新邏輯功能。FPGA 的靈活性可以保護(hù)投資,事實(shí)上,微軟現(xiàn)在的 FPGA 玩法與最初的設(shè)想大不相同。
2.數(shù)據(jù)中心是租給不同的租戶使用的,如果有的機(jī)器上有神經(jīng)網(wǎng)絡(luò)加速卡,有的機(jī)器上有必應(yīng)搜索加速卡,有的機(jī)器上有網(wǎng)絡(luò)虛擬化加速卡,任務(wù)的調(diào)度和服務(wù)器的運(yùn)維會(huì)很麻煩。使用 FPGA 可以保持?jǐn)?shù)據(jù)中心的同構(gòu)性。
接下來看通信密集型任務(wù)。相比計(jì)算密集型任務(wù),通信密集型任務(wù)對(duì)每個(gè)輸入數(shù)據(jù)的處理不甚復(fù)雜,基本上簡單算算就輸出了,這時(shí)通信往往會(huì)成為瓶頸。對(duì)稱加密、防火墻、網(wǎng)絡(luò)虛擬化都是通信密集型的例子。
通信密集型任務(wù),CPU、GPU、FPGA、ASIC 的數(shù)量級(jí)比較(以 64 字節(jié)網(wǎng)絡(luò)數(shù)據(jù)包處理為例)
對(duì)通信密集型任務(wù),F(xiàn)PGA 相比 CPU、GPU 的優(yōu)勢(shì)就更大了。從吞吐量上講,F(xiàn)PGA 上的收發(fā)器可以直接接上 40 Gbps 甚至 100 Gbps 的網(wǎng)線,以線速處理任意大小的數(shù)據(jù)包;而 CPU 需要從網(wǎng)卡把數(shù)據(jù)包收上來才能處理,很多網(wǎng)卡是不能線速處理 64 字節(jié)的小數(shù)據(jù)包的。盡管可以通過插多塊網(wǎng)卡來達(dá)到高性能,但 CPU 和主板支持的 PCIe 插槽數(shù)量往往有限,而且網(wǎng)卡、交換機(jī)本身也價(jià)格不菲。
從延遲上講,網(wǎng)卡把數(shù)據(jù)包收到 CPU,CPU 再發(fā)給網(wǎng)卡,即使使用 DPDK 這樣高性能的數(shù)據(jù)包處理框架,延遲也有 4~5 微秒。更嚴(yán)重的問題是,通用 CPU 的延遲不夠穩(wěn)定。例如當(dāng)負(fù)載較高時(shí),轉(zhuǎn)發(fā)延遲可能升到幾十微秒甚至更高(如下圖所示);現(xiàn)代操作系統(tǒng)中的時(shí)鐘中斷和任務(wù)調(diào)度也增加了延遲的不確定性。
ClickNP(FPGA)與 Dell S6000 交換機(jī)(商用交換機(jī)芯片)、Click+DPDK(CPU)和 Linux(CPU)的轉(zhuǎn)發(fā)延遲比較,error bar 表示 5% 和 95%。來源:[5]
雖然 GPU 也可以高性能處理數(shù)據(jù)包,但 GPU 是沒有網(wǎng)口的,意味著需要首先把數(shù)據(jù)包由網(wǎng)卡收上來,再讓 GPU 去做處理。這樣吞吐量受到 CPU 和/或網(wǎng)卡的限制。GPU 本身的延遲就更不必說了。
那么為什么不把這些網(wǎng)絡(luò)功能做進(jìn)網(wǎng)卡,或者使用可編程交換機(jī)呢?ASIC 的靈活性仍然是硬傷。盡管目前有越來越強(qiáng)大的可編程交換機(jī)芯片,比如支持 P4 語言的 Tofino,ASIC 仍然不能做復(fù)雜的有狀態(tài)處理,比如某種自定義的加密算法。
綜上,在數(shù)據(jù)中心里 FPGA 的主要優(yōu)勢(shì)是穩(wěn)定又極低的延遲,適用于流式的計(jì)算密集型任務(wù)和通信密集型任務(wù)。