多核編程時代來臨 你準備好了嗎?
如今具有上千個內(nèi)核的集群已經(jīng)司空見慣了。在普通的臺式機和筆記本電腦中可以見到具有數(shù)百個內(nèi)核的GPU芯片,這些芯片除了完成圖形處理任務外,現(xiàn)在還被用于計算事務。
為目前的服務器、臺式機和筆記本電腦系統(tǒng)編程相對來說還比較簡單。不過,隨著內(nèi)核數(shù)量呈1個或2個數(shù)量級的增加,事情變得越來越具有挑戰(zhàn)性。舉例來說,服務器可能包含多個多核芯片,每個芯片可向?qū)ΨQ多處理(SMP)系統(tǒng)提供數(shù)十個支持虛擬機(VM)的內(nèi)核,從而允許系統(tǒng)運行數(shù)百個虛擬機。
過去,一般使用高速總線或交換系統(tǒng)鏈接芯片內(nèi)的多個內(nèi)核。但***架構(gòu)傾向于采用非統(tǒng)一內(nèi)存架構(gòu)(NUMA)方法。芯片通常含有大量片上內(nèi)存(采用一級、二級或三 級緩存的形式)。Intel、AMD和其它公司還為內(nèi)核配置了多個內(nèi)存控制器。
片上內(nèi)核可以快速訪問它們的一級緩存,但由于數(shù)據(jù)遠離內(nèi)核,因此具有較長的延時。片外訪問請求通過芯片互連進行傳送。當這些請求沒有期望的信息時,Intel和AMD采用芯片之間的多個點到點連接并通過相鄰芯片傳送這些請求。
遺憾的是,發(fā)送到數(shù)量極其龐大的內(nèi)核要求采用不同的方法,如網(wǎng)格或更常見的網(wǎng)絡/集群技術。諸如串行快速I/O(SRIO)、InfiniBand和以太網(wǎng)等網(wǎng)絡接口就經(jīng)常被用來實現(xiàn)集群。消息包用來處理通信事務。與片上通信相比,此時的延時一般較長。
SRIO具有最少的開銷和最小的數(shù)據(jù)包,并提供端到端的握手。InfiniBand一般用于處理較大的消息,是許多超級計算機集群的***。以太網(wǎng)具有明顯的開銷和延時問題,但使用十分普及,已經(jīng)成為互聯(lián)網(wǎng)的最主要接口。這三種接口都可以用于片外通信,但對于片上通信而言,設計變化較大。
SMP NUMA芯片
許多公司正在致力于研究具有數(shù)百甚至數(shù)千個內(nèi)核的芯片,一些公司現(xiàn)在已經(jīng)可以供貨。Tilera公司的64位Tile-Gx產(chǎn)品線非常適合通信應用,而該公司的***產(chǎn)品還可以滿足云和服務器集群要求(參見electronicdesign.com網(wǎng)站上發(fā)表的“Single Chip Packs In 100 VLIW Cores”)。Adapteva公司的32位Epiphany(圖1)架構(gòu)則支持嵌入式信號處理(參見electronicdesign.com網(wǎng)站上發(fā)表的“Multicore Array Targets Embedded Applications”)。

圖1:Adaptewa的Epiphany 32位內(nèi)核通過矩形的網(wǎng)格鏈接在一起。
Tilera和Adapteva公司給每個處理內(nèi)核都配套了通信交換機,該交換機是通信網(wǎng)格的一部分。每個內(nèi)核有自己的實現(xiàn)方式和特點,但它們非常類似,因為網(wǎng)格由多種通信網(wǎng)絡組成,可承載不同類型的信息。
Tilera在這種網(wǎng)絡中還加入了緩存支持功能,因為該公司實現(xiàn)了一種復雜的緩存一致機制,允許將內(nèi)核組織起來形成“計算島”。這些內(nèi)核允許隔離,因此單顆芯片可以一次運行多個操作環(huán)境。對這些區(qū)域中的內(nèi)存的訪問操作相同,與所涉及的內(nèi)核無關,因為緩存是分布式的,但這也給訪問與另一個內(nèi)核相關的數(shù)據(jù)帶來了額外延時。
Adapteva的內(nèi)核也存在類似的訪問延時問題和功能,但這些內(nèi)核沒有任何本地緩存。同樣,所有內(nèi)核都能訪問系統(tǒng)中的所有內(nèi)存。每個內(nèi)核有32kB的存儲器供代碼和數(shù)據(jù)共享。這種方法使編程人員需承擔更多的責任,但極大地簡化了芯片設計。該方法還能降低復雜性和對電源的要求。Epiphany內(nèi)核主要用于嵌入式應用,該類應用中,設計人員通常需要管理整個系統(tǒng),而安全等細節(jié)要求并沒有提升。
這兩種方法只是強調(diào)了編程人員在處理大量內(nèi)核時面臨的一些挑戰(zhàn)。只有大部分內(nèi)核在做有用工作時,這些系統(tǒng)才是高效的。在單顆內(nèi)核上運行串行算法無法從相鄰內(nèi)核獲得任何優(yōu)勢。

Intel公司的Larrabee(參見electronicdesign.com網(wǎng)站上發(fā)表的“Intel Makes Some Multicore Lemonade”)催生了Intel的22nm Knights Corner多集成內(nèi)核(MIC)平臺(圖2)。Knights Corner擁有32個支持四線程的1.5GHz內(nèi)核,總共支持128個線程。Knights Corner還在使用了環(huán)的內(nèi)核間提供緩存一致性。這種環(huán)在Larrabee中使用過,可連接到GDDR5(圖形化雙倍數(shù)據(jù)速率第5版)內(nèi)存控制器、I/O和一些固定功能邏輯(圖3)。

圖3:Knight Corner平臺通過一個高速環(huán)連接Intel架構(gòu)(IA)內(nèi)核。
共享內(nèi)存可用于進程間通信,并用來實現(xiàn)消息傳遞系統(tǒng)。換句話說,一些硬件設計用硬件實現(xiàn)消息傳遞,這樣可以簡化軟件設計。當多芯片系統(tǒng)創(chuàng)建出來后,這些系統(tǒng)將更容易發(fā)展。
消息傳遞芯片與系統(tǒng)
消息傳遞網(wǎng)格網(wǎng)絡在Intel的單芯片云計算機(SCC)上將24個片(tile)聯(lián)結(jié)在一起。每一片有一個5端口的路由器,其中一個端口專屬于兩個x86 IA內(nèi)核。這兩個內(nèi)核共享一個16MB的消息緩存。每個內(nèi)核有自己的一級和二級緩存。4個DDR3(雙倍數(shù)據(jù)速率3)內(nèi)存控制器分布于通信網(wǎng)格的四周。
這種網(wǎng)格網(wǎng)絡具有2TB/s的帶寬。與Adapteva的Epiphany類似,SCC使用固定的X-Y路由機制。區(qū)別在于,Epiphany工作在字級,而Intel的芯片工作在消息級。SCC路由器支持兩個消息類,可實現(xiàn)8個虛擬通道。
SeaMicro公司沒有把許多內(nèi)核放到單顆芯片上,而是用256個雙內(nèi)核、1.66GHz Intel Atom N570芯片搭建了一個系統(tǒng)(參見electronicdesign.com網(wǎng)站上發(fā)布的“512 64-Bit Atom Cores In 10U Rack”)。有個1.28Tb/s的環(huán)形結(jié)構(gòu)連接著這些64位芯片。消息傳遞用于芯片之間的通信。這種環(huán)形結(jié)構(gòu)還能將處理器連接到SATA存儲控制器和以太網(wǎng)控制器。
多道程序設計方法
并行編程方法多種多樣,有時取決于基本的硬件架構(gòu)。許多方法要求共享內(nèi)存,而基于消息的解決方案可以被映射到各種架構(gòu)。
消息傳遞接口(MPI)包含大多數(shù)網(wǎng)絡平臺都提供的基本套接字。采用最基本的形式時,消息傳遞接口是任務之間面向字符或面向記錄的管道。通過消除與二進制數(shù)據(jù)有關的許多問題,可擴展標記語言(XML)改變了數(shù)據(jù)向四周傳遞的方式,但這需要花費更多的編程開銷。
MPI論壇提供的MPI標準庫經(jīng)常用于任務級并行編程通信,它支持從集群到大量并行機器的所有設備。
MPI規(guī)范包括進程、組和通信器。一個進程可以屬于一個或多個組。通信器提供了進程之間的鏈路,并包含一組有效參與者。內(nèi)部通信器在組內(nèi)工作。中間通信器在組間工作。通信器的創(chuàng)建和銷毀是動態(tài)進行的。
OpenMP(開放式多處理)是一種共享內(nèi)存的應用編程接口(API),經(jīng)常與SMP系統(tǒng)一起使用。編譯器內(nèi)部的支持是必須的,C、C++和Fortran等眾多編程語言都可以獲得OpenMP支持。OpenMP比MPI簡單,但缺乏細微的任務控制機制,而且不支持GPU。
多內(nèi)核協(xié)會(MCA)設計的規(guī)范不僅提供了系統(tǒng)之間的互操作性,而且提供了操作系統(tǒng)之間的可移植性。其OpenMCAPI(開放多內(nèi)核通信API)可促進基本的多內(nèi)核共享內(nèi)存通信。
MCAPI 1.0規(guī)范發(fā)布于2008年,它定義了輕量級進程間通信(IPC)系統(tǒng),這種系統(tǒng)支持種類廣泛的環(huán)境,包括SMP、不對稱多處理(AMP)、集群甚至ASIC和FPGA。
MCAPI提供基本的消息傳遞支持,可以幫助開發(fā)人員在上面搭建更為復雜的系統(tǒng)。MCAPI能夠充分發(fā)揮共享內(nèi)存系統(tǒng)和其它架構(gòu)的優(yōu)勢。MCA多內(nèi)核資源管理API(MRAPI)作為MCAPI的有效補充,提供了應用級的資源管理功能。MRAPI可應用于SMP和AMP系統(tǒng)。
共享內(nèi)存系統(tǒng)本身可用于矩陣操作,像GPU那樣的多內(nèi)核平臺也運作良好。MathWorks公司的Matlab因為支持數(shù)字運算而非常出名,它不僅可以利用多內(nèi)核SMP系統(tǒng),還能充分利用GPU功能(參見electronicdesign.com網(wǎng)站上發(fā)表的“Mathworks Matlab GPU Q And A”)。Matlab可以隱藏基本的計算系統(tǒng)。一些Matlab應用程序在GPU上運行時可以取得顯著的加速效果,但許多Matlab應用程序在CPU上運行得一樣好甚至更好。
憑借NVidia GPU的CUDA功能,GPU開創(chuàng)了非圖形化顯示應用的先河(參見electronicdesign.com網(wǎng)站上發(fā)表的“SIMT Architecture Delivers Double-Precision Teraflops”)。NVidia的CUDA支持C、C++和Fortran等編程語言,但正如指出的那樣,僅適用于NVidia硬件。
Kronos Group的OpenCL(開放計算語言)是可以在各種GPU和CPU上運行的一種更為通用的解決方案(參見electronicdesign.com網(wǎng)站上發(fā)表的“Match Multicore With Multiprogramming”)。OpenCL提供了與CUDA相似的架構(gòu)和功能。
在OpenCL術語中,內(nèi)核(kernel)是一個可以在GPU等器件上運行的函數(shù),可以被主程序調(diào)用。內(nèi)核有點類似于遠程過程調(diào)用(RPC)。OpenCL可以在同時也是主機的CPU上運行,但一般情況下OpenCL用于充分發(fā)掘其它計算資源的優(yōu)勢。
OpenCL內(nèi)核具有一個與之關聯(lián)的OpenCL程序。程序所做的工作在ND-Range環(huán)境中進行定義,這種環(huán)境包含了工作組(work-group),而工作組又包含了工作項(work-item)。工作項與CUDA線程是一樣的。OpenCL模型基于的是GPU中采用的單指令多線程(SIMT)架構(gòu)。
工作項執(zhí)行計算任務。工作組定義了工作項相互之間如何進行通信。SIMT方法有許多線程在處理不同的數(shù)據(jù),但運行相同的代碼。雖然不是所有應用程序都能很好地映射到這種架構(gòu),但還是許多應用程序可以做到這一點,GPU可以將性能較CPU提高10至100倍,因為GPU內(nèi)部具有數(shù)百個內(nèi)核。
主應用程序定義了使用OpenCL API的所有組件,包括器件上的內(nèi)存分配,并提供內(nèi)核程序。這種內(nèi)核程序以源碼形式提供,在運行時編譯。這種方法提供了可移植性,并且因為計算過程通常在大型數(shù)據(jù)數(shù)陣列上完成,可將開銷減至最小。
同樣,編譯只在內(nèi)核建立時執(zhí)行一次,而不是每次調(diào)用內(nèi)核時都要執(zhí)行。發(fā)往內(nèi)核的參數(shù)將進入隊列,從而使得主機能以異步方式提供數(shù)據(jù)。結(jié)果從隊列消息中讀取。
CUDA和OpenCL對并行計算來說相對較新,面向的是數(shù)據(jù)并發(fā)機制。目標管理集團(OMG),也即統(tǒng)一建模語言(UML)的傳播者,做了許多工作來標準化并行計算。
UML可以用來定義并行處理,但大多數(shù)編程人員更愿意使用基于其它OMG規(guī)范的工具,如公共對象請求代理架構(gòu)(CORBA)(參見electronicdesign.com網(wǎng)站上發(fā)表的“Software Frameworks Tackle Load Distribution”)和數(shù)據(jù)分布式服務(DDS)(參見electronicdesign.com網(wǎng)站上發(fā)布的“DDS V1.0 Standardizes Publish/Subscribe”)。
分布式任務
CORBA提供了一個遠程過程調(diào)用環(huán)境,這一環(huán)境可在協(xié)同操作任務的異類網(wǎng)絡中工作。CORBA使用了一種接口定義語言(IDL)來規(guī)范數(shù)據(jù)如何在系統(tǒng)之間映射,從而允許基本系統(tǒng)匯集可能具有不同格式、壓縮率或編碼(如小端與大端格式整數(shù))的數(shù)據(jù)。CORBA為所有主要的編程語言(如Ada、C、C++、Java甚至COBOL和Python)提供了標準映射,并為許多其它語言提供了非標準的實現(xiàn)。
CORBA也使用對象請求代理(ORB)。ORB提供了對由ORB組成的CORBA網(wǎng)絡的程序訪問。ORB額外提供許多服務,包括目錄服務、調(diào)度和事務處理。來自不同源的ORB可以在一起工作。
CORBA實現(xiàn)一般都較大,可滿足復雜的應用需求。多個系統(tǒng)提供相似的服務,如微軟的DCOM(分布式組件對象模型)和.NET框架或Java的遠程方法調(diào)用(RMI)。一些方法提供更適合嵌入式系統(tǒng)的較輕量級環(huán)境。其它方法則提供了層次化的實現(xiàn),這允許低端節(jié)點成為更復雜環(huán)境的一部分。
OMG DDS代表用于數(shù)據(jù)分發(fā)的一類發(fā)布/訂閱方法,但它有別于RPC方法。利用DDS,數(shù)據(jù)源將把信息發(fā)布為主題,不管有多少訂閱者都能訪問這些主題。數(shù)據(jù)在可用或改變時即向外提供。
DDS可能像CORBA一樣復雜,因為涉及許多問題,包括匯集、流控制、服務質(zhì)量和安全等細節(jié)。其它發(fā)布/訂閱接口的復雜性通常都沒DDS高,因為它們被設計為與特定的操作系統(tǒng)或語言一起使用。同樣,有許多途徑將并行通信方法混合在一起。
微軟的分散軟件服務(DSS)是一種輕量級、REST風格(代表性狀態(tài)轉(zhuǎn)移)、基于.NET的運行時環(huán)境,最初是微軟機器人開發(fā)平臺(RDS)的一部分(參見electronicdesign.com網(wǎng)站上發(fā)布的“Frameworks Make Robotics Development Easy—Or Easier, At Least”)。當然,輕量級是一個相對術語,因為DSS相當深奧復雜。
DSS設計為在并發(fā)和協(xié)調(diào)運行時(CCR)之上運行,而CCR也是機器人開發(fā)平臺(RDS)的一部分。事實表明,DSS對其它應用來說也非常有用。DSS是一種基于web的技術,因此每個DSS節(jié)點都有一個通用資源標識符。DSS提供了一種動態(tài)發(fā)布和識別服務的機制。
對機器人技術來說,微軟DSS/CCR的另外一種替代技術是開源機器人操作系統(tǒng)(ROS)(參見electronidesign.com網(wǎng)站上發(fā)布的“Cooperation Leads To Smarter Robots”)。ROS同樣基于web,但它將諸如安全等許多問題轉(zhuǎn)移到了外部網(wǎng)絡支持。
并行語言
諸如MathWorks的Matlab等編程語言在處理矩陣操作時提供了并行操作功能,可充分發(fā)揮GPU(如果有的話)的優(yōu)勢。并行計算工具箱增加了語言功能,如并行的for循環(huán)、特殊的數(shù)組類型和并行的數(shù)字函數(shù)。
Intel的Parallel Studio遵循相似的方法(參見electronicdesign.com網(wǎng)站上發(fā)表的“Dev Tools Target Parallel Processing”)。其功能特性包括線程創(chuàng)建模塊(TBB),該模塊用于表達基于C++任務的并行機制(參見electronicdesign.com網(wǎng)站上發(fā)布的“Parallel Programming Is Here To Stay”)。***版本提供諸如parallel_pipeline等函數(shù),這種函數(shù)提供了強類型、lambda友好的管線接口。
Parallel Studio的另外一個部分是Intel的Cilk++軟件開發(fā)套件(SDK)。Cilk++是通過Parallel Studio C/C++編譯器對C++進行的并行擴展。它增加了cilk_for、cilk_spawn和cilk_sync等關鍵詞。與大多數(shù)并行編程語言擴展一樣,Cilk++設計允許任務的低開銷創(chuàng)建、管理和同步。運行時支持負載均衡、同步和任務間通信。
像Java等一些編程語言已經(jīng)具有先進的任務管理功能。Ada就是一種非常成熟的編程語言,在研究并行編程時應加以考慮。Ada對任務管理的支持非常好,在要求高度安全和可靠性的應用中使用Ada說明了為何該語言有助于大型復雜的并行處理應用。
愛立信(Ericsson)最初為電話管理應用開發(fā)了Erlang編程語言。這種語言使用演員模型進行并發(fā)處理。Erlang也像Java一樣提供自動碎片收集功能。函數(shù)式語言子集有嚴格的評估、單賦值和動態(tài)類型。對于并行編程來說,函數(shù)式編程語言具有許多優(yōu)勢。
Haskell是最重要的函數(shù)式編程語言之一(參見electronicdesign.com網(wǎng)站上發(fā)表的“Embedded Functional Programming Using Haskell”)。由于Haskell同樣還用于研究,因而并行編程支持處于不斷變化中。某種方法采用的“策略”可以針對特定應用或主機進行調(diào)整。
Haskell的Hindley-Milnet全局類型推論在處理并行算法時可提供許多優(yōu)勢,但函數(shù)式編程的單賦值(不可變的變量)、惰性評估以及Monads的使用將使習慣于C/C++和Java的編程人員感到困惑。
谷歌(Google)的Go和Scala是全新設計的兩種語言,與Haskell相比更加傳統(tǒng),可提供并發(fā)編程環(huán)境(參見electronicdesign.com網(wǎng)站上發(fā)表的“If Your Programming Language Doesn’t Work, Give Scala A Try”)。這兩種語言吸收了函數(shù)式編程和其它編程語言的許多長處。Scala雖然不是Java的超集,但非常接近。
Go包含了被稱為goroutines的輕量級線程,這些線程使用圖案匹配通道進行通信。Scala在Java虛擬機(JVM)上運行,它包含了具有收集接口的并行收集功能,但可以使用并行語義處理內(nèi)容。
美國國家儀器(NI)公司的LabVIEW是少數(shù)幾種數(shù)據(jù)流編程語言中的其中一種(參見electronicdesign.com網(wǎng)站上發(fā)表的“LabVIEW 2010 Hits NI Week”)。數(shù)據(jù)流語義允許并行出現(xiàn)計算任務,而LabVIEW應用程序可以很好地映射到包括FPGA和GPU在內(nèi)的并行硬件。LabVIEW的圖形化特性使得并行操作對編程人員來說更加透明。
并行編程有許多種選擇。像Cilk++或OpenCL等逐步增強型語言可能適合許多場合使用,但開發(fā)人員也不應忽視那些更加激進的變化。
原文:http://laoyaoba.com/ss6/html/08/n-241608.html
【編輯推薦】