FPGA,你為什麼這麼牛?

買賣虛擬貨幣

最近幾年,fpga這個概念越來越多地出現。

例如,比特幣挖礦,就有使用基於fpga的礦機。還有,之前微軟表示,將在資料中心裡,使用fpga“代替”cpu,等等。

其實,對於專業人士來說,fpga並不陌生,它一直都被廣泛使用。但是,大部分人還不是太瞭解它,對它有很多疑問——fpga到底是什麼?為什麼要使用它?相比 cpu、gpu、asic(專用晶片),fpga有什麼特點?……

今天,帶著這一系列的問題,我們一起來——揭秘fpga


一、為什麼使用 fpga?

眾所周知,通用處理器(cpu)的摩爾定律已入暮年,而機器學習和 web 服務的規模卻在指數級增長。

人們使用定製硬體來加速常見的計算任務,然而日新月異的行業又要求這些定製的硬體可被重新程式設計來執行新型別的計算任務。

fpga 正是一種硬體可重構的體系結構。它的英文全稱是field programmable gate array,中文名是現場可程式設計門陣列。

fpga常年來被用作專用晶片(asic)的小批次替代品,然而近年來在微軟、百度等公司的資料中心大規模部署,以同時提供強大的計算能力和足夠的靈活性。

不同體系結構效能和靈活性的比較


fpga 為什麼快?「都是同行襯托得好」。

cpu、gpu 都屬於馮·諾依曼結構,指令譯碼執行、共享記憶體。fpga 之所以比 cpu 甚至 gpu 能效高,本質上是無指令、無需共享記憶體的體系結構帶來的福利。

馮氏結構中,由於執行單元(如 cpu 核)可能執行任意指令,就需要有指令儲存器、譯碼器、各種指令的運算器、分支跳轉處理邏輯。由於指令流的控制邏輯複雜,不可能有太多條獨立的指令流,因此 gpu 使用 simd(單指令流多資料流)來讓多個執行單元以同樣的步調處理不同的資料,cpu 也支援 simd 指令。

而 fpga 每個邏輯單元的功能在重程式設計(燒寫)時就已經確定,不需要指令。

馮氏結構中使用記憶體有兩種作用。一是儲存狀態,二是在執行單元間通訊。

由於記憶體是共享的,就需要做訪問仲裁;為了利用訪問區域性性,每個執行單元有一個私有的快取,這就要維持執行部件間快取的一致性。

對於儲存狀態的需求,fpga 中的暫存器和片上記憶體(bram)是屬於各自的控制邏輯的,無需不必要的仲裁和快取。

對於通訊的需求,fpga 每個邏輯單元與周圍邏輯單元的連線在重程式設計(燒寫)時就已經確定,並不需要透過共享記憶體來通訊。

說了這麼多三千英尺高度的話,fpga 實際的表現如何呢?我們分別來看計算密集型任務和通訊密集型任務。

計算密集型任務的例子包括矩陣運算、影象處理、機器學習、壓縮、非對稱加密、bing 搜尋的排序等。這類任務一般是 cpu 把任務解除安裝(offload)給 fpga 去執行。對這類任務,目前我們正在用的 altera(似乎應該叫 intel 了,我還是習慣叫 altera……)stratix v fpga 的整數乘法運算效能與 20 核的 cpu 基本相當,浮點乘法運算效能與 8 核的 cpu 基本相當,而比 gpu 低一個數量級。我們即將用上的下一代 fpga,stratix 10,將配備更多的乘法器和硬體浮點運算部件,從而理論上可達到與現在的頂級 gpu 計算卡旗鼓相當的計算能力。


fpga 的整數乘法運算能力(估計值,不使用 dsp,根據邏輯資源佔用量估計)


fpga 的浮點乘法運算能力(估計值,float16 用軟核,float 32 用硬核)


在資料中心,fpga 相比 gpu 的核心優勢在於延遲。

像 bing 搜尋排序這樣的任務,要儘可能快地返回搜尋結果,就需要儘可能降低每一步的延遲。

如果使用 gpu 來加速,要想充分利用 gpu 的計算能力,batch size 就不能太小,延遲將高達毫秒量級。

使用 fpga 來加速的話,只需要微秒級的 pcie 延遲(我們現在的 fpga 是作為一塊 pcie 加速卡)。

未來 intel 推出透過 qpi 連線的 xeon + fpga 之後,cpu 和 fpga 之間的延遲更可以降到 100 納秒以下,跟訪問主存沒什麼區別了。

fpga 為什麼比 gpu 的延遲低這麼多?

這本質上是體系結構的區別。

fpga 同時擁有流水線並行和資料並行,而 gpu 幾乎只有資料並行(流水線深度受限)。

例如處理一個資料包有 10 個步驟,fpga 可以搭建一個 10 級流水線,流水線的不同級在處理不同的資料包,每個資料包流經 10 級之後處理完成。每處理完成一個資料包,就能馬上輸出。

而 gpu 的資料並行方法是做 10 個計算單元,每個計算單元也在處理不同的資料包,然而所有的計算單元必須按照統一的步調,做相同的事情(simd,single instruction multiple data)。這就要求 10 個資料包必須一起輸入、一起輸出,輸入輸出的延遲增加了。

當任務是逐個而非成批到達的時候,流水線並行比資料並行可實現更低的延遲。因此對流式計算的任務,fpga 比 gpu 天生有延遲方面的優勢。

計算密集型任務,cpu、gpu、fpga、asic 的數量級比較(以 16 位整數乘法為例,數字僅為數量級的估計


asic 專用晶片在吞吐量、延遲和功耗三方面都無可指摘,但微軟並沒有採用,出於兩個原因:

?  資料中心的計算任務是靈活多變的,而 asic 研發成本高、週期長。好不容易大規模部署了一批某種神經網路的加速卡,結果另一種神經網路更火了,錢就白費了。fpga 只需要幾百毫秒就可以更新邏輯功能。fpga 的靈活性可以保護投資,事實上,微軟現在的 fpga 玩法與最初的設想大不相同。

?  資料中心是租給不同的租戶使用的,如果有的機器上有神經網路加速卡,有的機器上有 bing 搜尋加速卡,有的機器上有網路虛擬化加速卡,任務的排程和伺服器的運維會很麻煩。使用 fpga 可以保持資料中心的同構性。

接下來看通訊密集型任務。

相比計算密集型任務,通訊密集型任務對每個輸入資料的處理不甚複雜,基本上簡單算算就輸出了,這時通訊往往會成為瓶頸。對稱加密、防火牆、網路虛擬化都是通訊密集型的例子。


通訊密集型任務,cpu、gpu、fpga、asic 的數量級比較(以 64 位元組網路資料包處理為例,數字僅為數量級的估計)


對通訊密集型任務,fpga 相比 cpu、gpu 的優勢就更大了。

從吞吐量上講,fpga 上的收發器可以直接接上 40 gbps 甚至 100 gbps 的網線,以線速處理任意大小的資料包;而 cpu 需要從網絡卡把資料包收上來才能處理,很多網絡卡是不能線速處理 64 位元組的小資料包的。儘管可以透過插多塊網絡卡來達到高效能,但 cpu 和主機板支援的 pcie 插槽數量往往有限,而且網絡卡、交換機本身也價格不菲。


從延遲上講,網絡卡把資料包收到 cpu,cpu 再發給網絡卡,即使使用 dpdk 這樣高效能的資料包處理框架,延遲也有 4~5 微秒。更嚴重的問題是,通用 cpu 的延遲不夠穩定。例如當負載較高時,轉發延遲可能升到幾十微秒甚至更高(如下圖所示);現代作業系統中的時鐘中斷和任務排程也增加了延遲的不確定性。


clicknp(fpga)與 dell s6000 交換機(商用交換機晶片)、click+dpdk(cpu)和 linux(cpu)的轉發延遲比較,error bar 表示 5% 和 95%。來源:[5]

雖然 gpu 也可以高效能處理資料包,但 gpu 是沒有網口的,意味著需要首先把資料包由網絡卡收上來,再讓 gpu 去做處理。這樣吞吐量受到 cpu 和/或網絡卡的限制。gpu 本身的延遲就更不必說了。

那麼為什麼不把這些網路功能做進網絡卡,或者使用可程式設計交換機呢?asic 的靈活性仍然是硬傷。

儘管目前有越來越強大的可程式設計交換機晶片,比如支援 p4 語言的 tofino,asic 仍然不能做複雜的有狀態處理,比如某種自定義的加密演算法。

綜上,在資料中心裡 fpga 的主要優勢是穩定又極低的延遲,適用於流式的計算密集型任務和通訊密集型任務。


二、微軟部署 fpga 的實踐

2016 年 9 月,《連線》(wired)雜誌發表了一篇《微軟把未來押注在 fpga 上》的報道 [3],講述了 catapult 專案的前世今生。

緊接著,catapult 專案的老大 doug burger 在 ignite 2016 大會上與微軟 ceo satya nadella 一起做了 fpga 加速機器翻譯的演示。

演示的總計算能力是 103 萬 t ops,也就是 1.03 exa-op,相當於 10 萬塊頂級 gpu 計算卡。一塊 fpga(加上板上記憶體和網路介面等)的功耗大約是 30 w,僅增加了整個伺服器功耗的十分之一。


ignite 2016 上的演示:每秒 1 exa-op (10^18) 的機器翻譯運算能力




微軟部署 fpga 並不是一帆風順的。對於把 fpga 部署在哪裡這個問題,大致經歷了三個階段:

?  專用的 fpga 叢集,裡面插滿了 fpga
?  每臺機器一塊 fpga,採用專用網路連線
?  每臺機器一塊 fpga,放在網絡卡和交換機之間,共享伺服器網路


微軟 fpga 部署方式的三個階段,來源:[3]


第一個階段是專用叢集,裡面插滿了 fpga 加速卡,就像是一個 fpga 組成的超級計算機。

下圖是最早的 bfb 實驗板,一塊 pcie 卡上放了 6 塊 fpga,每臺 1u 伺服器上又插了 4 塊 pcie 卡。

最早的 bfb 實驗板,上面放了 6 塊 fpga。來源:[1]


可以注意到該公司的名字。在半導體行業,只要批次足夠大,晶片的價格都將趨向於沙子的價格。據傳聞,正是由於該公司不肯給「沙子的價格」 ,才選擇了另一家公司。

當然現在資料中心領域用兩家公司 fpga 的都有。只要規模足夠大,對 fpga 價格過高的擔心將是不必要的。


最早的 bfb 實驗板,1u 伺服器上插了 4 塊 fpga 卡。來源:[1]


像超級計算機一樣的部署方式,意味著有專門的一個機櫃全是上圖這種裝了 24 塊 fpga 的伺服器(下圖左)。

這種方式有幾個問題:

?  不同機器的 fpga 之間無法通訊,fpga 所能處理問題的規模受限於單臺伺服器上 fpga 的數量;
?  資料中心裡的其他機器要把任務集中發到這個機櫃,構成了 in-cast,網路延遲很難做到穩定。
?  fpga 專用機櫃構成了單點故障,只要它一壞,誰都別想加速了;
?  裝 fpga 的伺服器是定製的,冷卻、運維都增加了麻煩。


部署 fpga 的三種方式,從中心化到分散式。來源:[1]


一種不那麼激進的方式是,在每個機櫃一面部署一臺裝滿 fpga 的伺服器(上圖中)。這避免了上述問題 (2)(3),但 (1)(4) 仍然沒有解決。

第二個階段,為了保證資料中心中伺服器的同構性(這也是不用 asic 的一個重要原因),在每臺伺服器上插一塊 fpga(上圖右),fpga 之間透過專用網路連線。這也是微軟在 isca'14 上所發表論文采用的部署方式。


open compute server 在機架中。來源:[1]



open compute server 內景。紅框是放 fpga 的位置。來源:[1]



插入 fpga 後的 open compute server。來源:[1]



fpga 與 open compute server 之間的連線與固定。來源:[1]


fpga 採用 stratix v d5,有 172k 個 alm,2014 個 m20k 片上記憶體,1590 個 dsp。板上有一個 8gb ddr3-1333 記憶體,一個 pcie gen3 x8 介面,兩個 10 gbps 網路介面。一個機櫃之間的 fpga 採用專用網路連線,一組 10g 網口 8 個一組連成環,另一組 10g 網口 6 個一組連成環,不使用交換機。


機櫃中 fpga 之間的網路連線方式。來源:[1]


這樣一個 1632 臺伺服器、1632 塊 fpga 的叢集,把 bing 的搜尋結果排序整體效能提高到了 2 倍(換言之,節省了一半的伺服器)。

如下圖所示,每 8 塊 fpga 穿成一條鏈,中間用前面提到的 10 gbps 專用網線來通訊。這 8 塊 fpga 各司其職,有的負責從文件中提取特徵(黃色),有的負責計算特徵表示式(綠色),有的負責計算文件的得分(紅色)。

fpga 加速 bing 的搜尋排序過程。來源:[1]



fpga 不僅降低了 bing 搜尋的延遲,還顯著提高了延遲的穩定性。來源:[4]


本地和遠端的 fpga 均可以降低搜尋延遲,遠端 fpga 的通訊延遲相比搜尋延遲可忽略。來源:[4]


fpga 在 bing 的部署取得了成功,catapult 專案繼續在公司內擴張。


微軟內部擁有最多伺服器的,就是雲端計算 azure 部門了。

azure 部門急需解決的問題是網路和儲存虛擬化帶來的開銷。azure 把虛擬機器賣給客戶,需要給虛擬機器的網路提供防火牆、負載均衡、隧道、nat 等網路功能。由於雲端儲存的物理儲存跟計算節點是分離的,需要把資料從儲存節點透過網路搬運過來,還要進行壓縮和加密。

在 1 gbps 網路和機械硬碟的時代,網路和儲存虛擬化的 cpu 開銷不值一提。隨著網路和儲存速度越來越快,網路上了 40 gbps,一塊 ssd 的吞吐量也能到 1 gb/s,cpu 漸漸變得力不從心了。

例如 hyper-v 虛擬交換機只能處理 25 gbps 左右的流量,不能達到 40 gbps 線速,當資料包較小時效能更差;aes-256 加密和 sha-1 簽名,每個 cpu 核只能處理 100 mb/s,只是一塊 ssd 吞吐量的十分之一。


網路隧道協議、防火牆處理 40 gbps 需要的 cpu 核數。來源:[5]


為了加速網路功能和儲存虛擬化,微軟把 fpga 部署在網絡卡和交換機之間。

如下圖所示,每個 fpga 有一個 4 gb ddr3-1333 dram,透過兩個 pcie gen3 x8 介面連線到一個 cpu socket(物理上是 pcie gen3 x16 介面,因為 fpga 沒有 x16 的硬核,邏輯上當成兩個 x8 的用)。物理網絡卡(nic)就是普通的 40 gbps 網絡卡,僅用於宿主機與網路之間的通訊。


azure 伺服器部署 fpga 的架構。來源:[6]


fpga(smartnic)對每個虛擬機器虛擬出一塊網絡卡,虛擬機器透過 sr-iov 直接訪問這塊虛擬網絡卡。原本在虛擬交換機裡面的資料平面功能被移到了 fpga 裡面,虛擬機器收發網路資料包均不需要 cpu 參與,也不需要經過物理網絡卡(nic)。這樣不僅節約了可用於出售的 cpu 資源,還提高了虛擬機器的網路效能(25 gbps),把同資料中心虛擬機器之間的網路延遲降低了 10 倍。


網路虛擬化的加速架構。來源:[6]


這就是微軟部署 fpga 的第三代架構,也是目前「每臺伺服器一塊 fpga」大規模部署所採用的架構。

fpga 複用主機網路的初心是加速網路和儲存,更深遠的影響則是把 fpga 之間的網路連線擴充套件到了整個資料中心的規模,做成真正 cloud-scale 的「超級計算機」。

第二代架構裡面,fpga 之間的網路連線侷限於同一個機架以內,fpga 之間專網互聯的方式很難擴大規模,透過 cpu 來轉發則開銷太高。

第三代架構中,fpga 之間透過 ltl (lightweight transport layer) 通訊。同一機架內延遲在 3 微秒以內;8 微秒以內可達 1000 塊 fpga;20 微秒可達同一資料中心的所有 fpga。第二代架構儘管 8 臺機器以內的延遲更低,但只能透過網路訪問 48 塊 fpga。為了支援大範圍的 fpga 間通訊,第三代架構中的 ltl 還支援 pfc 流控協議和 dcqcn 擁塞控制協議。


縱軸:ltl 的延遲,橫軸:可達的 fpga 數量。來源:[4]



fpga 內的邏輯模組關係,其中每個 role 是使用者邏輯(如 dnn 加速、網路功能加速、加密),外面的部分負責各個 role 之間的通訊及 role 與外設之間的通訊。來源:[4]



fpga 構成的資料中心加速平面,介於網路交換層(tor、l1、l2)和傳統伺服器軟體(cpu 上執行的軟體)之間。來源:[4]


透過高頻寬、低延遲的網路互聯的 fpga 構成了介於網路交換層和傳統伺服器軟體之間的資料中心加速平面。

除了每臺提供雲服務的伺服器都需要的網路和儲存虛擬化加速,fpga 上的剩餘資源還可以用來加速 bing 搜尋、深度神經網路(dnn)等計算任務。


對很多型別的應用,隨著分散式 fpga 加速器的規模擴大,其效能提升是超線性的。

例如 cnn inference,當只用一塊 fpga 的時候,由於片上記憶體不足以放下整個模型,需要不斷訪問 dram 中的模型權重,效能瓶頸在 dram;如果 fpga 的數量足夠多,每塊 fpga 負責模型中的一層或者一層中的若干個特徵,使得模型權重完全載入片上記憶體,就消除了 dram 的效能瓶頸,完全發揮出 fpga 計算單元的效能。

當然,拆得過細也會導致通訊開銷的增加。把任務拆分到分散式 fpga 叢集的關鍵在於平衡計算和通訊


從神經網路模型到 haas 上的 fpga。利用模型內的並行性,模型的不同層、不同特徵對映到不同 fpga。來源:[4]


在 micro'16 會議上,微軟提出了 hardware as a service (haas) 的概念,即把硬體作為一種可排程的雲服務,使得 fpga 服務的集中排程、管理和大規模部署成為可能。


hardware as a service (haas)。來源:[4]


從第一代裝滿 fpga 的專用伺服器叢集,到第二代透過專網連線的 fpga 加速卡叢集,到目前複用資料中心網路的大規模 fpga 雲,三個思想指導我們的路線:

?  硬體和軟體不是相互取代的關係,而是合作的關係;
?  必須具備靈活性,即用軟體定義的能力;
?  必須具備可擴放性(scalability)。


三、fpga 在雲端計算中的角色


最後談一點我個人對 fpga 在雲端計算中角色的思考。作為三年級博士生,我在微軟亞洲研究院的研究試圖回答兩個問題:

?  fpga 在雲規模的網路互連繫統中應當充當怎樣的角色?
?  如何高效、可擴放地對 fpga + cpu 的異構系統進行程式設計?

我對 fpga 業界主要的遺憾是,fpga 在資料中心的主流用法,從除微軟外的網際網路巨頭,到兩大 fpga 廠商,再到學術界,大多是把 fpga 當作跟 gpu 一樣的計算密集型任務的加速卡。然而 fpga 真的很適合做 gpu 的事情嗎?

前面講過,fpga 和 gpu 最大的區別在於體系結構,fpga 更適合做需要低延遲的流式處理,gpu 更適合做大批次同構資料的處理。

由於很多人打算把 fpga 當作計算加速卡來用,兩大 fpga 廠商推出的高層次程式設計模型也是基於 opencl,模仿 gpu 基於共享記憶體的批處理模式。cpu 要交給 fpga 做一件事,需要先放進 fpga 板上的 dram,然後告訴 fpga 開始執行,fpga 把執行結果放回 dram,再通知 cpu 去取回。

cpu 和 fpga 之間本來可以透過 pcie 高效通訊,為什麼要到板上的 dram 繞一圈?也許是工程實現的問題,我們發現透過 opencl 寫 dram、啟動 kernel、讀 dram 一個來回,需要 1.8 毫秒。而透過 pcie dma 來通訊,卻只要 1~2 微秒。


pcie i/o channel 與 opencl 的效能比較。縱座標為對數座標。來源:[5]


opencl 裡面多個 kernel 之間的通訊就更誇張了,預設的方式也是透過共享記憶體。

本文開篇就講,fpga 比 cpu 和 gpu 能效高,體系結構上的根本優勢是無指令、無需共享記憶體。使用共享記憶體在多個 kernel 之間通訊,在順序通訊(fifo)的情況下是毫無必要的。況且 fpga 上的 dram 一般比 gpu 上的 dram 慢很多。

因此我們提出了 clicknp 網路程式設計框架 [5],使用管道(channel)而非共享記憶體來在執行單元(element/kernel)間、執行單元和主機軟體間進行通訊。

需要共享記憶體的應用,也可以在管道的基礎上實現,畢竟 csp(communicating sequential process)和共享記憶體理論上是等價的嘛。clicknp 目前還是在 opencl 基礎上的一個框架,受到 c 語言描述硬體的侷限性(當然 hls 比 verilog 的開發效率確實高多了)。理想的硬體描述語言,大概不會是 c 語言吧。


clicknp 使用 channel 在 elements 間通訊,來源:[5]



clicknp 使用 channel 在 fpga 和 cpu 間通訊,來源:[5]


低延遲的流式處理,需要最多的地方就是通訊。

然而 cpu 由於並行性的限制和作業系統的排程,做通訊效率不高,延遲也不穩定。

此外,通訊就必然涉及到排程和仲裁,cpu 由於單核效能的侷限和核間通訊的低效,排程、仲裁效能受限,硬體則很適合做這種重複工作。因此我的博士研究把 fpga 定義為通訊的「大管家」,不管是伺服器跟伺服器之間的通訊,虛擬機器跟虛擬機器之間的通訊,程序跟程序之間的通訊,cpu 跟儲存裝置之間的通訊,都可以用 fpga 來加速。

成也蕭何,敗也蕭何。缺少指令同時是 fpga 的優勢和軟肋。

每做一點不同的事情,就要佔用一定的 fpga 邏輯資源。如果要做的事情複雜、重複性不強,就會佔用大量的邏輯資源,其中的大部分處於閒置狀態。這時就不如用馮·諾依曼結構的處理器。

資料中心裡的很多工有很強的區域性性和重複性:


一部分是虛擬化平臺需要做的網路和儲存,這些都屬於通訊;
另一部分是客戶計算任務裡的,比如機器學習、加密解密。

首先把 fpga 用於它最擅長的通訊,日後也許也會像 aws 那樣把 fpga 作為計算加速卡租給客戶。

不管通訊還是機器學習、加密解密,演算法都是很複雜的,如果試圖用 fpga 完全取代 cpu,勢必會帶來 fpga 邏輯資源極大的浪費,也會提高 fpga 程式的開發成本。更實用的做法是fpga 和 cpu 協同工作,區域性性和重複性強的歸 fpga,複雜的歸 cpu。

當我們用 fpga 加速了 bing 搜尋、深度學習等越來越多的服務;當網路虛擬化、儲存虛擬化等基礎元件的資料平面被 fpga 把持;當 fpga 組成的「資料中心加速平面」成為網路和伺服器之間的天塹……似乎有種感覺,fpga 將掌控全域性,cpu 上的計算任務反而變得碎片化,受 fpga 的驅使。以往我們是 cpu 為主,把重複的計算任務解除安裝(offload)到 fpga 上;以後會不會變成 fpga 為主,把複雜的計算任務解除安裝到 cpu 上呢?隨著 xeon + fpga 的問世,古老的 soc 會不會在資料中心煥發新生?

原帖連結:https://mp.weixin.qq.com/s/wwvc6821u5ealx9uq1osja

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;