在上一回中提到了CUDA,它是Nvidia所提出來的GPGPU的架構。為了讓程式設計者得以在此架構上開發應用程式,Nvidia還提供了一個CUDA C語言,使得程式設計者得以運用此語言來進行CUDA應用程式的開發。

這CUDA C語言,是以我們所熟知的C語法為基礎而設計出來,之所以這麼做,其主要目的就是讓程式設計者得以運用過去已經熟悉的語法,來進行GPGPU上的程式設計,而不需要重頭學習一個全新的語言以及程式設計的環境。

而CUDA是Nvidia所提出來的GPGPU的模型,可以想見的,CUDA僅能適用在Nvidia的產品之上。不過,想透過GPGPU方式來提供更多在計算效能可能性的,也不是僅有Nvidia一家。像AMD,也針對ATI自家的繪圖晶片,提供GPGPU的計算能力,並且提供了所謂Stream SDK,來開發自家晶片上的GPGPU應用程式。

各家硬體廠商自然自有盤算,但是,倘若各家都有不同的架構和開發應用程式的方式,那麼對程式設計者而言,勢必構成一大障礙。若是寫下的程式碼無法跨越不同晶片商的產品,那麼若是想同時兼容多種晶片架構時,在程式設計上就會顯得相當不便。不過,從程式設計環境的生態來看,只要有市場,這種兼容性的需求,就會試圖被滿足。而OpenCL就是其中一個。

OpenCL的興起與發展

OpenCL(Open Computing Language)最早是由蘋果所發起(同時擁有其商標權),和AMD、Nvidia、Intel、IBM等公司合作,一同制定草案,送交Khronos Group完成其規範。

OpenCL就和OpenGL及OpenAL類似,是針對某一個應用領域的程式設計需求,所制定的開放性程式庫規範。一如OpenGL是針對繪圖應用、OpenAL是針對音訊應用,而OpenCL所針對的,就是異構式的計算。

OpenCL在設計時,即針對在不同架構的CPU、GPU之上,進行異構計算的程式設計。因此,在OpenCL問世之前,利用CUDA所寫成的應用程式,就只能在Nvidia的顯示卡上執行,而基於Stream SDK所寫成的程式,也只能在ATI的顯示卡上運行。不過有了OpenCL之後,基於OpenCL所編寫的程式,就可以得到跨平臺的可攜性,在各家支援OpenCL的GPU上,就都可以一體適合而執行了。

為了提供一個兼容、具可攜性的規範及程式設計介面,OpenCL自然必須考慮到各家廠商既有GPGPU的架構,以及程式設計模型,使得可以在各種不同的GPGPU上,允許程式設計者使用標準的統一化介面來進行程式設計,也使得所寫下的程式碼,得以跨越不同硬體廠商架構的GPGPU,來編譯、執行。

從OpenCL的各項功能特色中,你可以看出各家廠商架構的影子。

例如,在OpenCL裡,kernel的執行是由多個執行緒所構成的,而且多個執行緒間可以構成一個群組,同一群組裡的執行緒間可以做同步,但是跨群組的執行緒就不行。還記得上一回談到CUDA時,我們提到的區塊(Block)和執行緒的關係嗎?它們基本上是相同的概念。

就像所有提供通用性介面的設計一樣,OpenCL必須從各家的實作中取出可共通的部份、隱藏掉特定實作中獨有的部份,這才有辦法讓基於OpenCL的程式得以對應到各家的實作上去。有一些特定實作中才有的特性,像是前一回中所提到的warp,就沒有被包含在OpenCL中,這代表著程式設計者無法自行運用這些特性,而只能交給編譯器或程式庫,讓它們利用這些各實作特有的性質來做最佳化。

OpenCL的軟體,主要可以分為三個部份,即平臺層(Platform layer)、執行期環境(Runtime),以及編譯器。

平臺層的作用,是用來管理可用於計算的設備,以及啟動、初始化這些設備。而執行期環境則是用於資源的管理,以及程式的執行。編譯器即為開發工具的部份,當然也包括語言的部份。其語言是在C語言規範C99的子集合下,進行了一些語法的擴充,構成了OpenCL專有的語言。

從上述的說明中不難明白,無論是CUDA或是OpenCL,都選擇了大多數程式設計者都熟悉的C語言語法,做為基礎去擴充,目的之一,為的當然是降低程式設計者入門的門檻。當然,C語言本身的優點,自也不在話下。

但是無論如何,在語法上都不是純粹的C語言,因為它們或多或少都做了擴充。

另一個值得關注的作法:C++ AMP

另一方面,除了OpenCL之外,微軟也針對這個應用領域,制定了所謂的C++ AMP(Accelertaed Massive Parallelism),而且,微軟的目標不單只是局限在CPU和GPGPU所組成的異構計算系統,而是試圖要將更多的可能性,例如多計算節點的異構計算系統給含括進來。

在C++ AMP的架構裡,可以有一個或多個的「加速器」,而在目前,程式開發人員可以運用的加速器就是GPU,不過,在C++ AMP的設計裡,未來是可以容納其他型式的加速器。

另外,C++ AMP基本上是個C++的程式庫,微軟並沒有對C++的語法做真正實質的改變,只是利用程式庫的型式,來滿足對異構計算的需求。這是C++ AMP的一個特點,所以程式設計者可以運用標準的C++語法,搭配這套支援C++ AMP的程式庫,即可撰寫異構計算的應用程式。而微軟在Visual Studio 2012中,即提供C++ AMP的支援,同時,在其整合開發環境中,提供了相當豐富的支援能力,包括對GPU的偵錯、中斷點設定、執行緒狀態,以及資料的察看等等。

事實上,C++AMP在設計時,已經考慮到幾個重要的原則:

(1)基於C++而非C,這一點和OpenCL,及CUDA等,都不相同。

(2)要能成為主流,所以在設計上盡量簡化程式設計模型。因為程式設計模型愈簡單,程式設計者愈容易上手,難度愈低就愈能吸引程式設計者使用,也就更有機會成為主流。

(3)盡可能少的改動,C++ AMP對C++沒有實質語法的改動,唯一的改變是使用了一個同名的關鍵字,但賦予了不同的用法。

(4)具可攜性,這使得用C++ AMP所寫成的應用程式,一樣可以在所支援的各廠商硬體上順利執行。

(5)要足夠通用,而且不會過期,所以C++ AMP特別封裝了「加速器」這個概念,使得日後要擴展到例如雲端上的加速器,也沒有問題。

(6)規格開放,所以C++ AMP並不是個封閉的產物,而是一個開放性的規格,這使得微軟以外的廠商,同樣也能基於此規格來進行實作。不過,目前剛起步的情況,也僅有微軟一家實作。

異構計算在這幾年間的發展,逐漸展露它的潛力及重要性,這使得它開始成為兵家競相爭逐之地。對於主要的架構、語言和工具,本文已略為一提,希望可以提供大要,讓有興趣的程式設計者做為參考,進而尋找更細節性的參考資訊。

在未來,對於想要提供高效計算的系統來說,異構計算勢必扮演舉足輕重的角色。

 

專欄作者

熱門新聞

Advertisement