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

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

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

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