大話眾核心處理器體系結構
2015-11-03 09:46:28 大話存儲塵世浮華迷人眼,夢中情境亦非真。朝若聞道夕可死,世間何處有高人?《聞道》,by 冬瓜哥。
前不久,冬瓜哥注意到了如下新聞,
倆毛頭小子獲得125萬美金投資,號稱其設計的CPU“顛覆”目前的體系結構,保持性能持平的前提下將功耗降低10~25倍。冬瓜哥略感到一股“互聯網+”的浮躁風潮,終于侵害到最后一片領地了。于是,冬瓜哥就想寫一篇關于眾核心CPU體系結構的布道文章了。
【主線1】從SMP/NUMA說起
多CPU在早期是通過一個共享總線比如FSB連接在一起,同樣掛接在FSB上還有內存控制器,橋控制器等,這種多個CPU共享訪問集中的RAM的架構成為SymmetricMulti Processor(SMP)架構,或者UMA(Uniform Memory Access)架構。如圖1所示。
圖1
后來共享總線改為了規格更高的交換式架構,所有CPU內部的關鍵功能部件全部放到一個Ring上,相當于地鐵環線一樣來運送數據,而多個環線之間,再使用交換式架構的分布式交換矩陣連接在一起。所以,CPU訪問自身環線上的內存控制器,速度很快,而訪問位于其他環線的MC,則需要通過分布式交換矩陣,整個內存空間還是多CPU共享而且可以直接尋址的,但是訪問距離近的MC,速度快時延低,訪問遠處的則速度慢時延高,所以為None Uniform Memory Access(NUMA)架構,如圖2所示。交換式架構可以擴展到更多CPU和RAM,比如32路Intel x86的服務器馬上就要出來了。
值得一提的是,在這個交換矩陣中,不一定非得用CPU內部的環線來掛內存,可以用任何方式將內存接入這個矩陣,也可以在這個交換矩陣的任何地方放置一個或者多個MC,掛一堆內存,然后用MC-QPI橋片接入QPI交換矩陣即可。典型的代表就是IBM x3950 x6產品系列中有個專門的1U箱子,里面全是內存。如圖3所示。
圖3
【主線2】AMP/異構計算
上述的體系中,所有CPU都是同樣的結構,OS啟動后,所有CPU地位都是相同的,可以調度任何線程到任何核心上運行,這叫做同構計算,同構的專業英文術語叫做homogeneous。而還有一種稱為Heterogeneous,意即異構。異構計算的一個典型例子就是超算,有些超算系統采用了GPU或者Intel Phi這類結構不太相同的CPU,來輔助主CPU的運算,其被稱為協處理器。然而,雖然是“協助”,其實協處理器在某些特殊結算場景下性能會幾倍甚至十幾倍于通用CPU。運行3D游戲就是個例子,顯卡上的GPU是協處理器,主CPU負責提供GPU充足的數據進行計算/渲染,GPU中數以千計的微型核心并行進行專用的計算,方能渲染出效果非凡的實時3D動畫。所以,異構計算,說白了,就是一個元帥,帶著幾個身強力壯的將軍打仗,元帥只管調度和發號施令,將軍則執行具體的軍事任務,上刀山下火海。這種體系被稱為Asymmetric Multi Processor(AMP)。
【支線】“能模擬地球”的Cell B.E處理器
IBM的Cell B.E處理器就是一款典型單芯片的片上AMP系統。尚未發布之前,IBM宣稱其性能爆表,秒殺同時代Intel CPU。后來不知道怎么回事,以訛傳訛,有人說Cell處理器可以承擔模擬整個地球的運算量,后“模擬地球”便指代Cell處理器,后來Cell處理器由于編程麻煩,已停止開發。但這不妨礙我們研究一下它,從中吸取一些營養。
其在同一顆芯片中集成了8個支持128位SIMD的專用RISC核心,以及一顆PowerPC通用核心,再加上內存控制器、IO控制器,所有部件連接在一個Ring環線上。如圖4所示。
圖4
操作系統,或者說主控程序,運行在PowerPC上,將任務數據和描述放到RAM中某個Queue,然后多個SIMD專用核心從這里取走任務、處理然后將結果寫回RAM,中斷PowerPC,處理、輸出。SIMD專用核心上運行自己的程序,這些程序與PowerPC上運行的程序沒有直接關系,這些程序各自看到各自的地址空間,也就是256KB的scratchpad ram,就是SRAM,和CPU的L1/2/3 Cache使用相同介質,只不過通用CPU的Cache是不可直接被程序尋址的,程序看不到Cache空間,而Cell處理器的SIMD核上的256KB Cache是可以直接尋址的,程序只能看到256KB的地址空間,代碼+數據不可超出256KB,所以這個核心的地址位數就可以是log2 256K。外部的DDR RAM并不被納入地址空間,而是像訪問硬盤一樣,將地址封裝到消息中,通過DMA引擎讀入到256KB的ScratchpadSRAM中處理,然后寫回。所以,外部DDR RAM不能直接尋址,代碼得先調用操作DMA引擎的庫來將數據載入本地256K SRAM。而傳統的通用CPU,這個過程完全不用軟件參與,軟件被編譯成機器碼之后,機器碼的操作地址直接可以是外部RAM的地址,而由硬件來負責直接存取外部RAM,所以,編寫通用CPU代碼的程序員,面對這種AMP體系,就感覺頭疼了。
比如,通用CPU在RAM和取值、LS單元之間會有一層Cache,并由硬件來管理,而Cell處理器內部的SIMD核并沒有管理Cache的硬件,實際上也并沒有Cache,其SRAM相當于RAM,其RAM相當于硬盤。代碼想要實現Cache預讀等緩沖操作,就需要自己開辟一塊空間作為Cache,自己管理預讀、寫回等,全軟件操作,這讓軟件開發者苦不堪言。Cell處理器率先被用在了索尼PS3游戲機中,這估計害苦了索尼機的游戲開發商了,不過即便如此,仍有頑皮狗這種頂尖團隊開發出《神秘海域1,2,3》系列和《美國末日》這種索尼平臺的經典游戲。最終,Cell停止開發。目前最新的游戲機比如PS4和XB1,都是x86體系的CPU+GPU,或者將二者做成一個芯片并以更高速的總線將CPU和GPU片內連接,稱之為APU。PS4平臺明年初會有超級大作《神秘海域4》出爐,冬瓜哥一直決定買臺PS4玩一玩,但是一直沒有時間來玩,也不知道什么時候能閑下來。
SIMD核心由于節省了這些硬件資源,縮小了電路面積,可以在一個芯片上設計更多數量的核心,對于并行計算場景有較大的加速效果。而其對于一些不可并行計算的場景,需要采用另一種任務調度方式,也可以達到較好的加速效果。詳見下文。
【主線2】NoC--眾核心處理器的關鍵
核心越來越多,如何來將這么多CPU核心之間、以及核心與RAM之間、以及核心與其他IO控制器之間,連接起來,成了一門獨立學科——Network on Chip(NoC)。上文中所述的Cell處理器,其NoC就是Ring環線。如果是幾百個核心,比如256核心/節點,利用Ring就不合適了,這個Ring網絡的“半徑”就是128,意即任何一個節點發出的消息,最差情況下要經過128次傳遞才會到達目標節點,時延太高,無法消受。所以,業界通常使用2D FullMesh網絡來連接如此多的部件。如圖5所示。
圖5
可以看到,每個核心通過NIC連接到一個路由器,路由器出4外部口,與其他CPU核心連接。這里所謂“NIC”只不過是一個網絡控制器,其連同Router被做在同一片電路模塊中,與CPU通過某種總線連接起來。當然,這些網絡并不是以太網等我們熟知的網絡,因為外部網絡很復雜,做了很多設計,NoC由于在芯片內部,可以做很多舍棄和專用設計,所以及其精簡和高效,電路面積很小。這種網絡的路由方式,基本都是被寫死的靜態路由,也就是哪個ID在哪,從哪個口走,都被初始化代碼定死,這樣就不需要動態路由協議了,削減了不必要的電路。
NoC有很多鏈接方式,比如下面這種就被稱為3D Torus網絡,如圖6所示。超算領域也需要將大量CPU連接到一起,也是使用這種方式,只不過超算領域的網絡拓撲更多樣,比如Fat Tree,HyperCube,FullMesh,Torus,Butter,以及各組合。所以,把眾核心芯片稱為片上HPC,也不足為過。
在NoC,每個器件,比如CPU核心、DDR控制器等,都有各自的節點ID,如果訪問的是DDR控制器后面的RAM,則程序需要將RAM地址封裝到消息中,并附上DDR控制器的節點ID,發送到NIC進行路由。
【支線】眾核共享內存—難求也!
有些眾核心不支持直接尋址DDRRAM,這就意味著多核心上的程序不能簡單的共享內存,比如我聲明某個變量在A地址,這個地址只是該程序所在核心能看到的本地地址,其他核心訪問不了另外核心的這個地址,所以,多個核心上的程序,就不能是一體的,而必須是獨立的,想交換數據的話,就得從外部DDR RAM走,而且自行控制加鎖和一致性,硬件不管,這又增加了編程的復雜度。
把DDR RAM當做IO方式來用,是有設計上的考量的,設計師完全可以加寬地址譯碼器,并增加硬件微控制器/譯碼器將地址請求轉換成NoC消息去訪存。設計師之所以將RAM搞成了IO,其原因有兩個,第一是節省這些譯碼硬件資源;第二則是提升吞吐量。第二點原因看上去不太應該,將直接訪存搞成IO還能提升吞吐量?這可能與很多思維背道而馳。理解這個問題需要的逼格比較高了。眾核心CPU核心內的流水線數量、級數都不會租的很多,不像通用CPU比如Power8系列一次直接發出8個LS請求,16條流水線并發。眾核心由于一個芯片上要做數百個核心,其只能降低核心內部控制邏輯的功能和復雜度,所以,其LS單元隊列深度很低,幾乎就是同步操作了,LS數據未返回之前,整個流水線就被stall了,嚴重影響吞吐量,而NoC鏈路相比QPI/HT等要慢得多,跳數也多,時延也就高,如果不用流水線高隊列深度異步請求的話,吞吐量根本上不來。所以,要想異步請求,好辦,那干脆就別直接用LS訪存了,代碼直接調用API將請求發出到NoC控制器封裝成消息發出去,這樣的話,在軟件層面實現異步IO,將底層隊列壓滿后,吞吐量方能上的來,但是大大增加了軟件的復雜度,處理數據之前,先批量將數據讀入本地內存,然后在本地處理,而不是處理一條數據訪存一次。傳統CPU上運行的程序,可以肆無忌憚的任性,絲毫不關心內存放在哪,怎么樣才最快。而眾核心上的程序,就得精打細算了,所以,眾核心基本被廣泛用于專用場景,比如防火墻、流處理、視頻處理等。大數據分析其實也很有應用潛力。
實際中,有些產品是同時支持走IO和直接尋址來訪問DDR RAM的,程序可以自行選擇,這一點就比較好了。
所謂NP,network processor,多半使用了這種眾核心架構,因為要達到充分的并行性,核心數越多,并行度越大。然而,通用CPU可以通過不斷的線程切換,也實現類似的Concurrency,所以現在一些個所謂SDN方案,軟件交換機,軟件路由器,看著也像那么回事,比如Intel使用DPDK庫來加速數據從網卡傳遞到內存的過程,至于收到包之后的處理,看上去通用CPU目前的性能,也還可以。但是通用平臺的一個劣勢就是其不提供外圍多樣的應加速器件,而專用的處理器可以集成一堆的應加速部件。當然,隨著工藝提升,Intel也正愁到底往芯片里塞點什么進去好呢?之前有些東西,塞進去過,又拿出來,又塞進去,愁人啊,干脆塞個FPGA進去算逑了,想弄點什么加速邏輯進去,換個固件就完了,當然,這是后話了。
【支線】PMC-Sierra公司代號Princeton的Flash控制器
凡是追求高并行度的,大量工序協作的專用場景,都可以用眾核心處理器。PMC-Sierra公司的Flash控制器就是一款16核心眾核處理器,采用2D Full Mesh NoC,16個核心連同PCIE控制器、Flash通道控制器、DDR控制器、多種硬加速器一起分布在該NoC上,采用消息機制傳遞數據,支持以IO方式訪問RAM,也支持直接將外部RAM空間映射到本地地址空間訪問,難能可貴。至于其固件是如何在16個核心上分配的,冬瓜哥就不繼續展開了。冬瓜哥畫了一張圖如下,如圖7所示。
【主線3】倆小子搞出來的NeoProcessor
被冬瓜哥打通了任督二脈之后,我們再回過頭來看一下最近這條新聞。兩個“毛頭小子”(圖8)弄出一個所謂“新體系結構”,詳見www.rexcomputing.com。
圖8
聲稱“In doing so, we are able to deliver a 10 to 25x increase in energyefficiency for the same performance level compared to existing GPU and CPUsystems”,這句話,冬瓜哥可以負責任的講,三個字,大忽悠。他可以說在某些專用場景下,超越目前的GPU和CPU,但是這句話說得太滿了,根本是不可能。只有那些想吸引投資的人,才會這么去忽悠,冬瓜哥認為這兩位兄弟,是用了所謂互聯網或者帶個加號的思維,來整CPU,投資人們眼前一亮,我尼瑪,CPU也可以是互聯網CPU啊,CPU也可以玩一把嘛?!巴ㄓ谩?a href="http://www.xebio.com.cn/cpu_soc" target="_blank" class="keylink">處理器,這個定位冬瓜哥感覺一開始就錯了。某些應用并行度很差,256個core根本沒用,這種應用,就算軟件更改之后跑在這種眾核心上,基本就是扯淡。
如圖所示,冬瓜哥并不清楚這倆小子到底有沒有用過Tilera的芯片,如果真的是“design from bottom”,那應該趁早打住重新審視一下老大哥Tilera今天是個什么狀況。圖9所示為這個Neo Processor的體系結構,乍一看與Tilera別無二致。
圖9
如果說這倆天才少年是想在軟件方面簡化開發的話,那無可厚非,如下圖10所示。其提供了一些基礎庫,避免程序自行去管理內存/Cache。但是這并不是什么顛覆性的東西。
“The Neo architecture addresses these problems by removingunnecessarycomplexity from hardware, resulting in smaller chip area and lesspowerconsumption, instead providing similar functionality more efficiently in arichsoftware toolchain.” “Wehave rethought computing architecture from theground up to design our Neo chip,featuring a completely new core design includingsoftware managed scratchpadmemory, 256 cores per chip, a mesh network-on-chipand a high bandwidthchip-to-chip interconnect.”
但愿這兩位天才少年在說上面這句話之前,已經全面考察了他們老前輩Cell B.E和Tilera的光輝事跡,他們是如何從一開始的閃光耀眼,走到最后人老珠黃的。不過,125萬美金,對于墻街來講九牛一毛,但可玩玩無妨,萬一玩出名堂來了呢,對吧。所以,這則新聞,外行看看熱鬧罷了。
【主線4】眾核心處理器的任務調度
非對稱式異構協作
在眾核心上調度任務,有兩種方式,一種是將同一個任務分層多步,每個核心執行其中一步,執行結果傳遞給下一個核心繼續處理下一步,流水線化之后,整體吞吐量可以上的來。比如防火墻,處理一個網絡數據包,需要經過多道工序,比如校驗、解析地址、排查ACL、匹配正則表達式等等等等,每個核心可以只做一件事,比如匹配ACL(可能使用到硬加速),一個包進來匹配完了走人,再下一個包,這樣,每個核心都全速運轉,只要匹配好每一步的速度。上述這種協作處理方式可以稱之為非對稱式異構協作,也就是每個核心處理不同數據的同一個子工序步驟,這也是現實中的工業生產流水線的常規做法。
對稱式同構協作
然而,有些業務,并不適合這樣處理,比如,3D圖像渲染時光線追蹤的計算,其計算過程中并不是我算完了扔給你我就不管了,而可能會回來追溯你讓你提供更多信息,這就麻煩大了,多個子工序之間有很強的關聯性,需要不斷的溝通交互數據,這一交互數據,就得走外部DDR RAM,此時時延大增,那么CPU只能原地空轉。面對這種場景,就需要切換到另一種調度方式上——對稱式同構協作。比如光纖追蹤計算,可以將要處理的圖像分割成多個切片,由總控程序將任務結構描述和數據放置在DDR RAM中,形成一個隊列,然后眾核心們從隊列中提取任務執行,并保證同步,也就是需要對隊列加鎖并標記,防止多個核心同時取到同一份任務的腦裂場景。多個核心并行處理完成每個切片的所有工序,工序之間有依賴沒有關系,因為是在同一個核心之內依賴,不牽扯到核心之間的數據交換,不會導致等待,最后由總控程序將結果匯總輸出。在這種調度方式下,每個核心之間完全不相關,各干各的。典型的比如數據搜索,1GB的數據,每個核心載入其中的一部分,然后搜,各搜各的,這也是Mapreduce的思想。
對于那些并發度本來就很少的業務,或者根本不可并發的業務,或者不可切分為多個獨立處理單元的數據,就得使用非對稱式異構協作了。這類業務如果是運行在普通通用CPU上,就得考慮將其流水線化工序化,并將每道工序映射為一個線程,靠CPU的線程切換完成輪轉,將流水線運作起來。