天天看點

多CPU程式開發: OpenMP-MPI(機群)和CUDA(GPU) - 艾斯1213

多CPU程式開發: OpenMP-MPI(機群)和CUDA(GPU)

CPU和GPU擅長和不擅長的方面

從它們執行運算的速度與效率的方面來探讨這個論題。

CPU和GPU都是具有運算能力的晶片,CPU更像“通才”——指令運算(執行)為重+ 數值運算,GPU更像“專才”——圖形類數值計算為核心。在不同類型的運算方面的速度也就決定了它們的能力——“擅長和不擅長”。晶片的速度主要取決于三個方面:微架構,主頻和IPC(每個時鐘周期執行的指令數)。

1.微架構

從微架構上看,CPU和GPU看起來完全不是按照相同的設計思路設計的,當代CPU的微架構是按照兼顧“指令并行執行”和“資料并行運算”的思路而設計,就是要兼顧程式執行和資料運算的并行性、通用性以及它們的平衡性。CPU的微架構偏重于程式執行的效率,不會一味追求某種運算極緻速度而犧牲程式執行的效率。

CPU微架構的設計是面向指令執行高效率而設計的,因而CPU是計算機中設計最複雜的晶片。和GPU相比,CPU核心的重複設計部分不多,這種複雜性不能僅以半導體的多寡來衡量,這種複雜性來自于實作:如程式分支預測,推測執行,多重嵌套分支執行,并行執行時候的指令相關性和資料相關性,多核協同處理時候的資料一緻性等等複雜邏輯。

GPU其實是由硬體實作的一組圖形函數的集合,這些函數主要用于繪制各種圖形所需要的運算。這些和像素,光影處理,3D 坐标變換等相關的運算由GPU硬體加速來實作。圖形運算的特點是大量同類型資料的密集運算——如圖形資料的矩陣運算,GPU的微架構就是面向适合于矩陣類型的數值計算而設計的,大量重複設計的計算單元,這類計算可以分成衆多獨立的數值計算——大量數值運算的線程,而且資料之間沒有像程式執行的那種邏輯關聯性。

GPU微架構複雜度不高,盡管半導體的數量不少。從應用的角度看,如何運用好GPU的并行計算能力主要的工作是開發好它的驅動程式。GPU驅動程式的優劣很大程度左右了GPU實際性能的發揮。

是以從微架構上看,CPU擅長的是像作業系統、系統軟體和通用應用程式這類擁有複雜指令排程、循環、分支、邏輯判斷以及執行等的程式任務。它的并行優勢是程式執行層面的,程式邏輯的複雜度也限定了程式執行的指令并行性,上百個并行程式執行的線程基本看不到。GPU擅長的是圖形類的或者是非圖形類的高度并行數值計算,GPU可以容納上千個沒有邏輯關系的數值計算線程,它的優勢是無邏輯關系資料的并行計算。

2.主頻

另外,GPU執行每個數值計算的速度并沒有比CPU快,從目前主流CPU和GPU的主頻就可以看出了,CPU的主頻都超過了1GHz,2GHz,甚至3GHz,而GPU的主頻最高還不到1GHz,主流的也就500~600MHz。要知道1GHz = 1000MHz。是以GPU在執行少量線程的數值計算時并不能超過CPU。

目前GPU數值計算的優勢主要是浮點運算,它執行浮點運算快是靠大量并行,但是這種數值運算的并行性在面對程式的邏輯執行時毫無用處。

3.IPC(每個時鐘周期執行的指令數)

這個方面,CPU和GPU無法比較,因為GPU大多數指令都是面向數值計算的,少量的控制指令也無法被作業系統和軟體直接使用。如果比較資料指令的IPC,GPU顯然要高過CPU,因為并行的原因。但是,如果比較控制指令的IPC,自然是CPU的要高的多。原因很簡單,CPU着重的是指令執行的并行性。

另外,目前有些GPU也能夠支援比較複雜的控制指令,比如條件轉移、分支、循環和子程式調用等,但是GPU程式控制這方面的增加,和支援作業系統所需要的能力CPU相比還是天壤之别,而且指令執行的效率也無法和CPU相提并論。

最後總結一下:

CPU擅長的:作業系統,系統軟體,應用程式,通用計算,系統控制等等;遊戲中人工智能,實體模拟等等;3D模組化-光線追蹤渲染;虛拟化技術——抽象硬體,同時運作多個作業系統或者一個作業系統的多個副本等等。

GPU擅長的:圖形類矩陣運算,非圖形類并行數值計算,高端3D遊戲。

綜上所述,在一台均衡計算的計算機系統中,CPU和GPU還是各司其職,除了圖形運算,GPU将來可能主要集中在高效率低成本的高性能并行數值計算,幫助CPU分擔這種類型的計算,提高系統這方面的性能。而目前的典型應用還是高端3D遊戲,一個高效的GPU配合一個高效的CPU,3D遊戲的整體效率才能得到保證。“高端3D遊戲隻需要高端顯示卡”或者“高端3D遊戲隻需要CPU”都是無稽之談。

OpenMP

OpenMP是由OpenMP Architecture Review Board牽頭提出的,并已被廣泛接受的,用于共享記憶體并行系統的多線程程式設計的一套指導性注釋(Compiler Directive)。OpenMP支援的程式設計語言包括C語言、C++和Fortran;而支援OpenMP的編譯器包括Sun

Compiler,GNU Compiler和Intel Compiler等。OpenMP提供了對并行算法的高層的抽象描述,程式員通過在源代碼中加入專用的pragma來指明自己的意圖,由此編譯器可以自動将程式進行并行化,并在必要之處加入同步互斥以及通信。當選擇忽略這些pragma,或者編譯器不支援OpenMP時,程式又可退化為通常的程式(一般為串行),代碼仍然可以正常運作,隻是不能利用多線程來加速程式執行。

  OpenMP提供的這種對于并行描述的高層抽象降低了并行程式設計的難度和複雜度,這樣程式員可以把更多的精力投入到并行算法本身,而非其具體實作細節。對基于資料分集的多線程程式設計,OpenMP是一個很好的選擇。同時,使用OpenMP也提供了更強的靈活性,可以較容易的适應不同的并行系統配置。線程粒度和負載平衡等是傳統多線程程式設計中的難題,但在OpenMP中,OpenMP庫從程式員手中接管了部分這兩方面的工作。

  但是,作為高層抽象,OpenMP并不适合需要複雜的線程間同步和互斥的場合。OpenMP的另一個缺點是不能在非共享記憶體系統(如計算機叢集)上使用。在這樣的系統上,MPI使用較多。

多執行緒的概念

  OpenMP是作為共享存儲标準而問世的。它是為在多處理機上編寫并行程式而設計的一個應用程式設計接口。它包括一套編譯指導語句和一個用來支援它的函數庫。

  目前雙核、四核的 CPU 當道,而六核的CPU也已經面世多時,是以在多處理機上編寫、運作并行程式會變得相當普遍。

  對於一般單一執行緒(single thread)的程式,多核心的處理器并沒有辦法提升它的處理效能;不過對於多執行緒(multi thread)的程式,就可以透過不同的核心同時計算,來達到加速的目的了!簡單的例子,以單執行緒的程式來說,一件事做一次要十秒的話,要做十次,都丢給同一顆核心做的話,自然就是

10 秒 * 10 次,也就是 100 秒了;但是以多執行緒的程式來說,它可以把這一件事,分給兩顆核心各自做,每顆核心各做 5 次,是以所需要的時間就隻需要 50 秒!

  當然,多執行緒的程式實際上沒這麼簡單。在工作的切割、結合上,也是要多花時間的,是以在現實中,即使最佳狀況,雙核心的效能也不會是 1 + 1 = 2 這樣的理想化。除此之外,也不是所有工作都是可以切割的!很多工作是有關聯性的,這樣如果直接切割給不同的處理核心各自去平行運算,出來的結果是肯定有問題的。而且,多執行緒的程式在編寫、維護上,也都比單一執行緒的程式複雜上不少。

  不過,如果電腦本身是多處理器、多核心處理器,或是處理器擁有像 Intel Hyper-Threading Technology

這類的能在同一個時間處理多個執行緒的功能的話,那把各自獨立的工作由單一執行緒改成多執行緒,在執行的效率上,大多還是會有增進的!

多執行緒的程式

  寫程式的時候該怎麼去寫多執行緒的程式呢?一般的方法,就是真的利用 thread 的控制,去實際在程式中去産生其他的 thread 來處理。像 POSIX Threads 這套 library,就是用來産生、控制執行緒的函式庫。而像 Microsoft VisualStudio 2005 中,也有提供控制

thread 的功能。這種方法,大多就是産生多個 thread,而再由主要的 thread 把工作拆開,分給各 thread 去運算,最後再由主要的 thread 回收結果、整合。

  但是,實際上要去控制 thread 是滿麻煩的~在程式的編寫上,也會複雜不少;而如果我們隻是想要把一些簡單的回圈平行化處理,用 thread library 來控制,實在有點殺雞用牛刀的感覺。這時候,用 Open MP 就簡單多了!OpenMP 是一種能透過高階指令,很簡單地将程式平行化、多執行緒化的

API;在最簡單的情形,甚至可以隻加一行指令,就可以将回圈内的程式平行化處理了!

OpenMP 的基本使用

  要在Visual

C++ 2005 中使用OpenMP其實不難,隻要将 Project 的Properties中C/C++裡Language的OpenMP Support開啟(參數為 /openmp),就可以讓VC++2005 在編譯時支援OpenMP 的文法了;而在編寫使用OpenMP

的程式時,則需要先include OpenMP的頭檔案:omp.h。

  而要将 for 回圈平行化處理,該怎麼做呢?非常簡單,隻要在前面加上一行

  #pragma omp parallel for

  就夠了!

  也可以實際用一段簡單的程式,來弄清楚它的運作方式。

#include <STDIO.H>

  #include <STDLIB.H>

  void Test(int n) {

  for (int i = 0; i < 10000; ++i)

  {

  //do nothing, just waste time

  }

  printf("%d, ", n);

  }

  int main(int argc, char* argv[])

  {

  for (int i = 0; i < 10; ++i)

  Test(i);

  system("pause");

  }

  上面的程式,在 main() 是一個很簡單的回圈,跑十次,每次都會調用Test()這個函數,并把是回圈的執行次數(i)傳進Test() 并列印出來。想當然,它的結果會是:

  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,

  而如果想利用 OpenMP把 main() 裡面的回圈平行化處理呢?隻需要修改成下面的樣子:

#include <omp.h>

  #include <stdio.h>

  #include <stdlib.h>

  void Test (int n) {

  for (int i = 0; i < 10000; ++i) {

  //do nothing, just waste time

  }

  printf("%d, ", n);

  }

  int main(int argc, char* argv[]) {

#pragma omp parallel for

for (int i = 0; i < 10; ++i)

  Test( i );

  system("pause");

  }

  夠簡單吧?重頭到尾,隻加了兩行!而執行後,可以發現結果也變了!

  0, 5, 1, 6, 2, 7, 3, 8, 4, 9,

  可以從結果很明顯的發現,他沒有照着0到9的順序跑了!而上面的順序怎麼來的?其實很簡單,OpenMP隻是把回圈 0 - 9 共十個步驟,拆成 0 - 4, 5 - 9 兩部份,丢給不同的執行緒去跑,是以數字才會出現這樣交錯性的輸出~

而要怎麼确定真的有跑多執行緒呢?如果本來有多處理器、多核心處理器或有 Hyper Thread 的話,一個單執行緒程式,最多隻會把一顆核心的使用量吃完;像比如說在 Pentium 4 HT 上跑,單一執行緒的程式,在工作管理者中看到的 CPU 使用率最多就是

50%。而利用 OpenMP 把回圈進行平行化處理後,就可以在執行回圈時,把兩顆核心的 CPU 都榨光了!也就是CPU 使用率是100%。

http://txl716.blog.163.com/blog/static/19353158200841792312627/

http://www.txrjy.com/baike/view.asp?OpenMP

MPI

1.Message

Passing Interface

三個英文單詞首字母的簡稱。具有代表性的有Message Passing Interface ,Multi Point Interface ,Multi points injection等。

  對MPI的定義是多種多樣的,但不外乎下面三個方面,它們限定了MPI的内涵和外延:   1、MPI是一個庫,而不是一門語言。許多人認為,MPI就是一種并行語言,這是不準确的。但是,按照并行語言的分類,可以把FORTRAN+MPI或C+MPI看作是一種在原來串行語言基礎之上擴充後得到的,并行語言MPI庫可以被FORTRAN77/C/Fortran90/C++調用,從文法上說,它遵守所有對庫函數/過程的調用規則,和一般的函數/過程沒有什麼差別;   2、MPI是一種标準或規範的代表,而不特指某一個對它的具體實作,迄今為止,所有的并行計算機制造商都提供對MPI的支援,可以在網上免費得到MPI在不同并行計算機上的實作,一個正确的MPI程式可以不加修改地在所有的并行機上運作;   3、MPI是一種消息傳遞程式設計模型,并成為這種程式設計模型的代表。事實上,标準MPI雖然很龐大,但是它的最終目的是服務于程序間通信這一目标的;   解釋來源于《高性能計算之并行程式設計技術——

MPI并行程式設計》都志輝 編著

4、MPI是多點接口(Multi Point Interface)的簡稱,是西門子公司開發的用于PLC之間通訊的保密的協定。MPI通訊是當通信速率要求不高、通信資料量不大時,可以采用的一種簡單經濟的通訊方式。MPI通信可使用PLC S7-200/300/400、操作面闆TP/OP及上位機MPI/PROFIBUS通信卡,如CP5512/CP5611/CP5613等進行資料交換。MPI網絡的通信速率為19.2Kbps~12Mbps,最多可以連接配接32個節點,最大通訊距離為50m,但是可能通過中斷器來擴充長度。

解釋來源于《西門子工業網絡通信指南》(上冊) 崔堅 主編

MPI(Message Passing Interface)是消息傳遞并行程式設計的标準之一,目前通用的是MPI1.1規範。正在制定的MPI2.0規範除支援消息傳遞外,還支援MPI的I/O規範和程序管理規範。MPI正成為并行程式設計事實上的工業标準。

  MPI的實作包括MPICH、LAM、IBM MPL等多個版本,最常用和穩定的是MPICH,曙光天潮系列的MPI以MPICH為基礎進行了定制和優化。

  MPICH含三層結構,最上層是MPI的API,基本是點到點通信,和在點到點通信基礎上構造的叢集通信(Collective Communication);中間層是ADI層(Abstract

Device Interface),其中device可以簡單地了解為某一種底層通信庫,ADI就是對各種不同的底層通信庫的不同接口的統一标準;底層是具體的底層通信庫,例如工作站機群上的p4通信庫、曙光1000上的NX庫、曙光3000上的BCL通信庫等。

  MPICH的1.0.12版本以下都采用第一代ADI接口的實作方法,利用底層device提供的通信原語和有關服務函數實作所有的ADI接口,可以直接實作,也可以依靠一定的模闆間接實作。自1.0.13版本開始,MPICH采用第二代ADI接口。

  我們将MPICH移植到曙光3000高效通信庫BCL(Basic Communication Library)上(簡稱MPI_BCL)。MPI_BCL的接口标準與MPICH版本1.1完全一緻,滿足MPI1.1标準。同時,也支援ch_p4的通信庫,即利用TCP/IP通信機制。從網絡硬體角度說,MPI_BCL針對系統網絡,MPI_ch_p4針對高速以太網。

書名: MPI并行程式設計執行個體教程

  作 者:張武生李建江 出版社: 清華大學出版社   出版時間:

2009 ISBN:

9787302186472   開本: 16   定價:

39.50 元

内容簡介

  《MPI并行程式設計執行個體教程》旨在通過示例全面介紹MP1并行程式開發庫的使用方法、程式設計技巧等方面的内容,力争完整讨論MP1規範所定義的各種特征。主要也括MPI環境下開發并行程式常用的方法、模式、技巧等内容。在内容組織上力求全面綜合地反映MPl-1和MPI-2規範。對MPI所定義的各種功能、特征分别給出可驗證和測試其工作細節的示例程式

編輯推薦

  ◆書中内容側重于以MPI庫為基礎開發并行應用程式,對MP規範定義的各項功能和特征在闡述其特點基礎上均配以執行個體加以說明和印證。   ◆書中所附執行個體盡量采用獨立的功能劃分,其中的代碼片段可直接用于并行應用程式開發   ◆在講述基本原理的同時,注重對各項消息傳遞和管理操作的功能及局限性、适用性進行分析進而使熟讀此書的讀者能夠編寫出适合應用特點,易維護、高效率的并行程式。   ◆與《MPI并行程式設計執行個體教程》配套的電子教案可在清華大學出版社網站下載下傳。

目錄

  第1章MPI并行環境及程式設計模型   1.1MPICH2環境及安裝和測試   1.1.1編譯及安裝   1.1.2配置及驗汪   1.1.3應用程式的編譯、連結   1.1.4運作及調試   1.1.5MPD中的安全問題   1.2MPI環境程式設計模型   1.2.1并行系統介紹   1.2.2并行程式設計模式   1.2.3MPI程式工作模式   1.3MPI消息傳遞通信的基本概念   1.3.1消息   1.3.2緩沖區   1.3.3通信子   1.3.4進樣号和l程序纰   1.3.5通價脅議   1.3.6隐形對象   第2章點到點通信   2.1阻糍通信   2.1.1标準通信模式   2.1.2緩沖通信模式   2.1.3就緒通信模式   2.1.4同步通信模式   2.1.5小結   2.2非阻塞通信   2.2.1通信結束測試   2.2.2非重複的非阻塞通信   2.2.3可醺複的非阻塞通信   2.2.4Probe和Cancel   2.3組合發送接收   2.3.1MPl_Send,MPI_RecvoMPl_Sendreev   2.3.2MPI_Bsend←→MPl_Sendrecv   2.3.3MPI_Rsend←→MPI_Sendrecv   2.3.4MPl_Ssend←→MPl_Sendrecv   2.3.5MPl_lsend←→MP1一Sendrecv   2.3.6MPl_Ibsend←→MPI_Sendrecv   2.3.7MPI_Irsend←→MPI_Sendrecv   2.3.8MPl_Issend,MPI_Irecv←→MPI_Sendrecv   2.3.9MPISend_init←→MPl_Sendrecv   2.3.10MPI一Bsendjinit←→MPl_Sendrecv   2.3.11MPI_Rsend_init←→MPI_Sendrecv   2.3.12MPl_Ssend_init,MPl_Recv_init←→MPl_Sendrecv   2.4點到點通信總結   2.4.1關于預防死鎖   2.4.2關于阻塞與非阻塞、同步與異步   2.4.3關于操作的執行順序及“公平性”   第3章組與通信子   3.1簡介   3.2組管理API   3.2.1組的建構及取消   3.2.2通路組的相關資訊和屬性   3.3組問通信   3.3.1建立與取消   3.3.2通路通信子資訊   3.4組間通信   3.4.1通路函數   3.4.2構造和取消函數   3.5屬性   3.5.1建立及釋放屬性操作   3.5.2通路屬性操作   3.5.3設定及删除屬性操作   3.5.4命名通信子對象   3.6錯誤處理   3.7組及通信子的小結   第4章集合通信   4.11←→N   4.1.1MPI_Bcast   4.1.2MPI_Scatter/MPI_Scatterv   4.2N←→1   4.2.1MPl_Gather/MPI_Gatherv  4.2.2MPI_Reduce   4.3N←→N   4.3.1MPI_Allgather/MPI_Allgatherv.   4.3.2MPI_Allreduce   4.3.3MPl_Reducescatter   4.3.4MPI_Alltoall/MPIAlltoallv/MPI_Alltoallw   4.3.5MPI_Scan/MPI_Exscan   4.4同步操作--MPI_Barrier   第5章資料類型   5.1類型圖   5.2與資料類型相關的API函數   5.2.1建立   5.2.2通路   5.2.3注冊與取消   5.3資料類型在通信函數緩沖區的構成   5.4資料類型的屬性   5.4.1屬性建立與釋放   5.4.2屬性操作   5.4.3複制資料類型   5.4.4類型屬性舉例   5.4.5資料類型命名   5.5資料類型的析構   5.5.1擷取建立資料類型MPI函數所使用參數數量資訊   5.5.2擷取建立資料類型MPI函數所使用實際參數資訊   5.5.3示例   5.6打包/解包   第6章程序拓撲   第7章動态程序管理   第8章單向通信/遠端記憶體通路   第9章并行I/O   第10章MPI與外部環境的資訊互動   第11章MPE   參考文獻

MPI并行程式設計

http://wenku.baidu.com/view/3d1a6df80242a8956bece43c.html

CUDA

CUDA(Compute Unified Device Architecture),顯示卡廠商NVidia推出的運算平台。 CUDA™是一種由NVIDIA推出的通用并行計算架構,該架構使GPU能夠解決複雜的計算問題。它包含了CUDA指令集架構(ISA)以及GPU内部的并行計算引擎。開發人員現在可以使用C語言來為CUDA™架構編寫程式,C語言是應用最廣泛的一種進階程式設計語言。所編寫出的程式于是就可以在支援CUDA™的處理器上以超高性能運作。将來還會支援其它語言,包括FORTRAN以及C++。

簡介  計算行業正在從隻使用CPU的“中央處理”向CPU與GPU并用的“協同處理”發展。為打造這一全新的計算典範,NVIDIA&reg;(英偉達™)發明了CUDA(Compute

Unified Device Architecturem,統一計算裝置架構)這一程式設計模型,是想在應用程式中充分利用CPU和GPU各自的優點。現在,該架構現已應用于GeForce&reg;(精視™)、ION™(翼揚™)、Quadro以及Tesla GPU(圖形處理器)上,對應用程式開發人員來說,這是一個巨大的市場。

  在消費級市場上,幾乎每一款重要的消費級視訊應用程式都已經使用CUDA加速或很快将會利用CUDA來加速,其中不乏Elemental Technologies公司、MotionDSP公司以及LoiLo公司的産品。

  在科研界,CUDA一直受到熱捧。例如,CUDA現已能夠對AMBER進行加速。AMBER是一款分子動力學模拟程式,全世界在學術界與制藥企業中有超過60,000名研究人員使用該程式來加速新藥的探索工作。

  在金融市場,Numerix以及CompatibL針對一款全新的對手風險應用程式釋出了CUDA支援并取得了18倍速度提升。Numerix為近400家金融機構所廣泛使用。

  CUDA的廣泛應用造就了GPU計算專用Tesla GPU的崛起。全球财富五百強企業現在已經安裝了700多個GPU叢集,這些企業涉及各個領域,例如能源領域的斯倫貝謝與雪佛龍以及銀行業的法國巴黎銀行。

  随着微軟Windows

7與蘋果Snow Leopard作業系統的問世,GPU計算必将成為主流。在這些全新的作業系統中,GPU将不僅僅是圖形處理器,它還将成為所有應用程式均可使用的通用并行處理器。

發展曆程

  随着顯示卡的發展,GPU越來越強大,而且GPU為顯示圖像做了優化。在計算上已經超越了通用的CPU。如此強大的晶片如果隻是作為顯示卡就太浪費了,是以NVidia推出CUDA,讓顯示卡可以用于圖像計算以外的目的。

  目前隻有G80、G92、G94、G96、GT200、GF100平台(即Geforce 8~Gecorce GTX480)的NVidia顯示卡才能使用CUDA,工具集的核心是一個C語言編譯器。G80中擁有128個單獨的ALU,是以非常适合并行計算,而且數值計算的速度遠遠優于CPU。

  CUDA的SDK中的編譯器和開發平台支援Windows、Linux系統,可以與Visual Studio2005內建在一起。

  Geforce8CUDA(Compute Unified Device Architecture)是一個新的基礎架構,這個架構可以使用GPU來解決商業、工業以及科學方面的複雜計算問題。它是一個完整的GPGPU解決方案,提供了硬體的直接通路接口,而不必像傳統方式一樣必須依賴圖形API接口來實作GPU的通路。在架構上采用了一種全新的計算體系結構來使用GPU提供的硬體資源,進而給大規模的資料計算應用提供了一種比CPU更加強大的計算能力。CUDA采用C語言作為程式設計語言提供大量的高性能計算指令開發能力,使開發者能夠在GPU的強大計算能力的基礎上建立起一種效率更高的密集資料計算解決方案。

  從CUDA體系結構的組成來說,包含了三個部分:開發庫、運作期環境和驅動(表2)。

  開發庫是基于CUDA技術所提供的應用開發庫。目前CUDA的1.1版提供了兩個标準的數學運算庫——CUFFT(離散快速傅立葉變換)和CUBLAS(離散基本線性計算)的實作。這兩個數學運算庫所解決的是典型的大規模的并行計算問題,也是在密集資料計算中非常常見的計算類型。開發人員在開發庫的基礎上可以快速、友善的建立起自己的計算應用。此外,開發人員也可以在CUDA的技術基礎上實作出更多的開發庫。

  運作期環境提供了應用開發接口和運作期元件,包括基本資料類型的定義和各類計算、類型轉換、記憶體管理、裝置通路和執行排程等函數。基于CUDA開發的程式代碼在實際執行中分為兩種,一種是運作在CPU上的宿主代碼(Host

Code),一種是運作在GPU上的裝置代碼(Device Code)。不同類型的代碼由于其運作的實體位置不同,能夠通路到的資源不同,是以對應的運作期元件也分為公共元件、宿主元件和裝置元件三個部分,基本上囊括了所有在GPGPU開發中所需要的功能和能夠使用到的資源接口,開發人員可以通過運作期環境的程式設計接口實作各種類型的計算。

  由于目前存在着多種GPU版本的NVidia顯示卡,不同版本的GPU之間都有不同的差異,是以驅動部分基本上可以了解為是CUDA-enable的GPU的裝置抽象層,提供硬體裝置的抽象通路接口。CUDA提供運作期環境也是通過這一層來實作各種功能的。目前基于CUDA開發的應用必須有NVIDIA CUDA-enable的硬體支援,NVidia公司GPU運算事業部總經理Andy

Keane在一次活動中表示:一個充滿生命力的技術平台應該是開放的,CUDA未來也會向這個方向發展。由于CUDA的體系結構中有硬體抽象層的存在,是以今後也有可能發展成為一個通用的GPGPU标準接口,相容不同廠商的GPU産品

CUDA™

工具包

  是一種針對支援CUDA功能的GPU(圖形處理器)的C語言開發環境。CUDA開發環境包括:

·

nvcc C語言編譯器

  · 适用于GPU(圖形處理器)的CUDA FFT和BLAS庫

·

分析器

  · 适用于GPU(圖形處理器)的gdb調試器(在2008年3月推出alpha版)

  · CUDA運作時(CUDA runtime)驅動程式(目前在标準的NVIDIA GPU驅動中也提供)

CUDA程式設計手冊

  CUDA開發者軟體開發包(SDK)提供了一些範例(附有源代碼),以幫助使用者開始CUDA程式設計。這些範例包括:

  · 并行雙調排序

  · 矩陣乘法

  · 矩陣轉置

  · 利用計時器進行性能評價

  · 并行大數組的字首和(掃描)

  · 圖像卷積

  · 使用Haar小波的一維DWT

  · OpenGL和Direct3D圖形互操作示例

  · CUDA BLAS和FFT庫的使用示例

  · CPU-GPU C—和C++—代碼內建

  · 二項式期權定價模型

  · Black-Scholes期權定價模型

  · Monte-Carlo期權定價模型

  · 并行Mersenne Twister(随機數生成)

  · 并行直方圖

  · 圖像去噪

  · Sobel邊緣檢測濾波器

  · MathWorks MATLAB&reg;

  新的基于1.1版CUDA的SDK 範例現在也已經釋出了。

技術功能

  · 在GPU(圖形處理器)上提供标準C程式設計語言

  · 為在支援CUDA的NVIDIA GPU(圖形處理器)上進行并行計算而提供了統一的軟硬體解決方案

  · CUDA相容的GPU(圖形處理器)包括很多:從低功耗的筆記本上用的GPU到高性能的,多GPU的系統。

  · 支援CUDA的GPU(圖形處理器)支援并行資料緩存和線程執行管理器

  · 标準FFT(快速傅立葉變換)和BLAS(基本線性代數子程式)數值程式庫

  · 針對計算的專用CUDA驅動

  · 經過優化的,從中央處理器(CPU)到支援CUDA的GPU(圖形處理器)的直接上傳、下載下傳通道

  · CUDA驅動可與OpenGL和DirectX圖形驅動程式實作互操作

  · 支援Linux 32位/64位以及Windows XP 32位/64位 作業系統

  · 為了研究以及開發語言的目的,CUDA提供對驅動程式的直接通路,以及彙編語言級的通路

其他資訊

  NVIDIA進軍高性能計算領域,推出了Tesla&CUDA高性能計算系列解決方案,CUDA技術,一種基于NVIDIA圖形處理器(GPU)上全新的并行計算體系架構,讓科學家、工程師和其他專業技術人員能夠解決以前無法解決的問題,作為一個專用高性能GPU計算解決方案,NVIDIA把超級計算能夠帶給任何工作站或伺服器,以及标準、基于CPU的伺服器叢集

  CUDA是用于GPU計算的開發環境,它是一個全新的軟硬體架構,可以将GPU視為一個并行資料計算的裝置,對所進行的計算進行配置設定和管理。在CUDA的架構中,這些計算不再像過去所謂的GPGPU架構那樣必須将計算映射到圖形API(OpenGL和Direct 3D)中,是以對于開發者來說,CUDA的開發門檻大大降低了。CUDA的GPU程式設計語言基于标準的C語言,是以任何有C語言基礎的使用者都很容易地開發CUDA的應用程式。

  由于GPU的特點是處理密集型資料和并行資料計算,是以CUDA非常适合需要大規模并行計算的領域。目前CUDA除了可以用C語言開發,也已經提供FORTRAN的應用接口,未來可以預計CUDA會支援C++、Java、Python等各類語言。可廣泛的應用在圖形動畫、科學計算、地質、生物、實體模拟等領域。

  2008年NVIDIA推出CUDA SDK2.0版本,大幅提升了CUDA的使用範圍。使得CUDA技術愈發成熟

目前

  支援CUDA的GPU銷量已逾1億,數以千計的軟體開發人員正在使用免費的CUDA軟體開發工具來解決各種專業以及家用應用程式中的問題。這些應用程式從視訊與音頻處理和實體效果模拟到石油天然氣勘探、産品設計、醫學成像以及科學研究,涵蓋了各個領域。目前市面上已經部署了超過一億顆支援CUDA的GPU,數以千計的軟體開發人員正在使用免費的CUDA軟體工具來為各種應用程式加速。

  CUDA 的核心有三個重要抽象概念: 線程組層次結構、共享存儲器、屏蔽同步( barrier

  synchronization),可輕松将其作為C 語言的最小擴充級公開給程式員。

  CUDA 軟體堆棧由幾層組成,一個硬體驅動程式,一個應用程式程式設計接口(API)

  和它的Runtime,還有二個進階的通用數學庫,CUFFT 和CUBLAS。硬體被設計成支援輕

  量級的驅動和Runtime 層面,因而提高性能。

  所支援的OS(operating system)

  CUDA目前支援linux和Windows作業系統。進行CUDA開發需要依次安裝驅動、toolkit、SDK三個軟體。在安裝目錄/C/src目錄下有很多的例程可以進行學習。

擴充閱讀:
  • 英偉摩達(NVIDIA摩機社群):http://www.nvmod.cn
  • http://cuda.csdn.net/zone_intro.html
  • http://live.csdn.net/Issue612/livePlay.aspx
  • http://www.nvidia.cn/object/what_is_cuda_new_cn.html
  • 《大規模并行處理器程式設計實戰》(英偉達官方網站推薦書籍)
  • 《CUDA範例精解》(英偉達官方網站推薦書籍)

NVIDIA CUDA技術亮點何在

  作為圖形晶片領域的領頭羊, NVIDIA(英偉達)認為GPU較CPU具有更強的浮點運算能力以及更大的帶寬等諸多優勢,甚至連半導體數量目前都是GPU略勝一籌,未來GPU将越來越多地取代CPU的資料處理職能。是以,英偉達在07年就提出了獨特的GPGPU(通用圖形處理器)概念。目前 NVIDIA(英偉達)新一代GPU都采用了統一渲染架構,這種架構相比以往使GPU的運算單元變得通用,并可以根據圖形渲染處理的負載靈活地改變運算單元的任務。這種架構內建了多個支援頂點坐标計算及三角形着色等多級處理的運算單元,各運算單元的任務可以根據各級處理的負載進行調整。新架構的出現也使得在以浮點運算為中心的通用進行中使用GPU成為可能。

  在這種趨勢下, NVIDIA(英偉達)定制了一個解決方案,被稱作Compute Unified Device Architecture,簡稱CUDA。這也就是今天我們介紹的主角!

  CUDA的編譯

  CUDA的本質是NVIDIA為自家的GPU編寫了一套編譯器NVCC極其相關的庫檔案。CUDA的應用程式擴充名可以選擇是.cu,而不是.cpp等。NVCC是一個預處理器和編譯器的混合體。當遇到CUDA代碼的時候,自動編譯為GPU執行的代碼,也就是生成調用CUDA Driver的代碼。如果碰到Host C++代碼,則調用平台自己的C++編譯器進行編譯,比如Visual Studio C++自己的Microsoft C++ Compiler。然後調用Linker把編譯好的子產品組合在一起,和CUDA庫與标準CC++庫連結成為最終的CUDA

Application。由此可見,NVCC模仿了類似于GCC一樣的通用編譯器的工作原理(GCC編譯CC++代碼本質上就是調用cc和g++)。整個CUDA平台是通過運用顯示卡内的流處理器進行數學運算,并通過GPU内部的緩存共享資料,流處理器之間甚至可以互相通信,同時對資料的存儲也不再限制于以GPU的紋理方式,存取更加靈活,可以充分利用統一架構的流輸出(stream out)特性,大大提高應用效率。

CUDA技術特色

  CUDA的運算

  目前的CUDA所用的運算方法是分開的,一部分由CPU負責,而另一部分通過CUDA編譯器使用GPU進行運算。在CUDA的架構下,一個程式分為兩個部份:host 端和device 端。Host 端是指在CPU 上執行的部份,而device 端則是在顯示晶片上執行的部份。Device端的程式又稱為 “kernel”。通常host端程式會将資料準備好後,複制到顯示卡的記憶體中,再由顯示晶片執行device端程式,完成後再由host端程式将結果從顯示卡的記憶體中取回。

由于顯示晶片大量并行計算的特性,它處理一些問題的方式,和一般CPU是不同的。比如在記憶體存取latency 的問題上,CPU 通常使用cache 來減少存取主記憶體的次數,以避免記憶體latency 影響到執行效率,而顯示晶片則多半沒有cache(或很小),而利用并行化執行的方式來隐藏記憶體的latency(即,當第一個 thread 需要等待記憶體讀取結果時,則開始執行第二個thread,依此類推),效率提高不少。正如 NVIDIA(英偉達)公司Tesla GPU計算事業部進階産品經理Sumit Gupta先生曾經推過一個形象的例子,CPU的順序指令執行操作好比是一間辦公室裡的多個職員,如果每人需要将杯子裡的水倒入同一個桶内時,他們需要排成長隊按順序進行。而對于GPU來說,這些職員無需排隊,隻要同時走到桶前将水倒入即可。是以,最适合利用CUDA處理的問題,是可以大量并行化的問題,才能有效隐藏記憶體的latency,并有效利用顯示晶片上的大量執行單元。使用CUDA

時,同時有上千個thread在執行是很正常的。是以,如果不能大量并行化的問題,使用CUDA就沒辦法達到最好的效率了。

GPU并行計算過程

  CPU存取顯示卡記憶體時隻能透過PCI Express 接口,是以速度較慢(PCI Express x16 的理論帶寬是雙向各4GB/s),是以不能過多進行這類動作,以免降低效率。在CUDA架構下,顯示晶片執行時的最小機關是thread。數個thread 可以組成一個block。一個block 中的thread 能存取同一塊共享的記憶體,而且可以快速進行同步的動作。每一個block 所能包含的thread 數目是有限的,不過執行相同程式的block,可以組成grid。不同block中的thread無法存取同一個共享的記憶體,是以無法直接互通或進行同步。是以,不同block中的thread能合作的程度是比較低的。不過,利用這個模式,可以讓程式不用擔心顯示晶片實際上能同時執行的thread數目限制。例如,一個具有很少量執行單元的顯示晶片,可能會把各個block中的thread順序執行,而非同時執行。不同的grid則可以執行不同的程式。

在目前支援CUDA的GPU中,其流處理器個數是不能和CPU現在擁有的核心數量作類比的。CPU的每一個核心都是一個完整的獨立處理架構,而GPU中的每個流處理器并不完全是這樣,而是以子組合方式運作,比如每8個流處理器組成一個Stream Multiprocessors (SM),其中分為四個流處理器又分為1小組,也可以看成是有兩組4D的SIMD處理器。需要說明的是,若使用者擁有超過兩張或以上支援CUDA的顯示卡,驅動程式将通過PCIe總線自動配置設定工作負載,進一步提升效能。

  當然CUDA也有其弱勢的地方,并不是所有的事情CUDA都能夠很好地解決,比如像作業系統這樣複雜的指令和紛繁的分支循環而又用很少的線程來處理,這顯然就不是CUDA的強項了。高度并行的計算是CUDA的技術特性之一。

  那些GPU支援CUDA?

  在推出GeForce GTX 200系列前,CUDA短短兩年時間就已經發展了四個版本:

不同CUDA版本對比

  目前,NVIDIA(英偉達)推出的GPU中,G80系列支援CUDA 1.0,而之後推出的G84、G86、G92、G94和G96 則支援CUDA 1.1。

GeForce顯示卡規格對比

CUDA 2.0—随GeForce GTX 200登場

  而NVIDIA(英偉達)在6月17日GeForce GTX 200系列釋出之時也推出了CUDA 2.0,加入雙精度運算支援,為應用提供更準确的運算結果,而這項技術源自于多重處理器的專用單元。

多重處理器的專用單元架構

  每一個多重處理器都包含了8個主要的FMAD處理器和8和MUL處理器來實作一些特殊功能的計算等。這樣,一個64位的FMAD處理器就産生了。但是這樣的處理器對于64位的計算能力相當低下,8X的低速FMAD和16X的低速FMUL都是導緻計算能力低下的原因。這個支援64位也意味着可以以它為模闆為将來的更進階和新一代的GPU發展提供代碼或者應用程式的支援,進而得到更好的甚至超過一個以上的64位處理器。每一個多重處理器都具有兩個流處理線,這樣就不必依賴周期而同時處理兩個信号。

  引入雙精度運算能力,可以在一定程度上增強GT200在科學計算領域的适用性.盡管在實際的相關領域中其實有部分甚至隻需要16位精度就足夠了,但GTX200核心的每一個SM都包括了一個雙精度64Bit浮點運算單元,是以每個周期GT200能達成1MAD*30SM=30MAD,在1.5GHz的shader頻率下可以達到90 GFLOPS(MAD)的雙精度浮點性能, NVIDIA(英偉達)對其稱之為可以與8核Xeon處理器(我想應該是指45nm Hypertown核心Xeon E5440 2.83GHz)的水準。不過需要注意的是,Xeon每個核心的浮點單元組合是每兩個周期完成一個ADDPD或者一個周期完成一個MULPD,在雙精度浮點峰值性能上"含金量"方面似乎要比GT200每個SM單周期MAD高一些。

NVIDIA(英偉達)的對手AMD在RV670上實作了硬體(非模拟)的FP64支援,雙精度MAD性能為單精度MAD的1/5,GT200架構的雙精度浮點支援應該是 NVIDIA(英偉達)邁向雙精度浮點加速器的第一步,未來的架構很可能會把浮點雙精度的性能做到單精度的1/2水準,這将是非常可觀的。

CUDA将成為又一個标準API接口

選擇CUDA的理由

  目前CUDA已經應用在很多領域,包括在通用計算中的一些GPU加速,遊戲中的實體模拟等等,而在科學計算中,CUDA可發揮的功效就更大了。比如有限元的計算、神經元的研究計算、地質分析等等科學研究的領域;當然目前GPU計算的應用還是處于一個早期的階段,大部分CUDA應用都是專業人員和相關的程式員在開發,随着CUDA的廣泛推行,以後會有實際的基于CUDA的程式,更多的程式員能夠加入進來,并且開發一些可以給大家日常應用帶來好處的程式,隻要有支援CUDA的GPU就能夠利用到GPU計算的好處。

提高多GPU程式設計與執行效率 CUDA 4.0初探

CUDA 4.0提高多GPU效率

  ● CUDA帶給GPU行業無限可能

  2007年可以說是GPU發展史上翻天覆地的一年,在這一年微軟推出了DirectX 10 API标準,将傳統的Pixel Shader(頂點着色器)、Vertex Shader(像素着色器)和Geometry Shader(幾何着色器),三種硬體邏輯被整合為一個全功能的統一着色器Shader。

  這種API發展思路背後是微軟和NVIDIA、AMD對于整個GPU發展曆程的思考與轉型。它标志着微軟開始支援GPU走向更強的可程式設計性,也标志着Intel等傳統CPU制造廠商在未來幾年将要面對GPU的強硬挑戰,越來越多的高性能計算機和超級計算機已經開始以GPU作為其運算能力提升的重要配件。

天河一号-A所采用的NVIDIA Tesla GPU

  2007年同樣是NVIDIA值得回憶的一年,NVIDIA公司在這一年正式推出了CUDA整套方案,它是一個完整的通用計算産品。CUDA是Compute Unified Device Architecture(統一計算架構)的簡稱,是建立在GPU基礎之上的通用計算開發平台,它是一個全新的軟硬體架構,可以将GPU視為一個并行資料計算的裝置,對所進行的計算進行配置設定和管理。

NVIDIA提出的CUDA通用計算方案

  簡單分析可知,CUDA是一種以C語言為基礎的平台,主要是利用顯示卡強大的浮點運算能力來完成以往需要CPU才可以完成的任務。這種整套方案的提出意味着程式員再也不用去鑽研繁雜的底層彙程式設計式,而是在C語言的基礎上稍加學習就能掌握CUDA并通過它來調用GPU強大的浮點運算能力。

CUDA 4.0的3個顯著提升

  這一版本的CUDA大幅度降低了程式設計難度,同時提升了GPU的程式設計和執行效率。CUDA 4.0主要的功能能夠在Fermi架構的最新GPU上被發揮出來,同時它可以讓G80、G92、GT200架構的GPU也擁有程式設計方式上的飛躍。

GPU統一虛拟尋址

  ● GPU統一虛拟尋址

  在2011年2月28日,NVIDIA釋出了最新版本的CUDA工具包——CUDA 4.0。借助該工具包,開發人員能夠開發出在GPU上運作的并行應用程式。本次NVIDIA曆經兩年時間釋出了CUDA 4.0版本,這一版本為我們帶來了3個核心的程式設計與執行方式提升,它們分别是:

  1、統一的虛拟尋址;

  2、更直接的GPU間通信;

  3、增強型C++模闆庫。

  這3個關鍵性提升讓更多開發人員能夠利用GPU計算,它們也成為CUDA 4.0的核心提升之處。接下來我們通過NVIDIA官方公布的資料來簡單分析CUDA 4.0的不同之處。

多個GPU及其顯存可以被視為一體

  首先提出的是“GPU統一虛拟尋址”概念,我們第一次見到這一概念在Fermi架構釋出的報道中,Fermi架構帶領GPU全面走向高性能計算的重要表現就在于存儲體系的結構完善和GPU統一的虛拟尋址,結構部分中關村線上顯示卡頻道之前進行了大量分析,細心的讀者肯定收藏了我們的技術分析類文章。

  Fermi的釋出徹底統一了GPU尋址空間,将不同的尋址簡化為一種指令,這在以前的的GPU中是不敢想象的,記憶體位址取決于存儲位置:最低位是本地,然後是共享,剩下的是全局。這種統一尋址空間也是支援C++的必需前提。

  本次CUDA 4.0版本的釋出可以讓多個GPU以及CPU統一調用GPU顯存以及CPU記憶體,并将處理器(CPU+GPU)和存儲器(記憶體+顯存)視為統一整體。在最大顯存為6GB的Tesla産品中,多CPU和多GPU融合之後可以為整個系統帶來大容量儲存設備并且進行統一尋址。

GPU通信和C++模闆庫

  ● GPU通信和C++模闆庫

  多GPU通信在以前的CUDA版本中代價很大,隻有專業的并行程式設計環境才能驅動多款GPU在同一系統内執行一個任務,而目前桌面級應用中,如果使用者的多塊顯示卡同時存在于系統中,一個CUDA加速程式往往隻能調用其中一個GPU核心。

從DirectX 10到DirectX 11的多線程變化

  雖然我們看到GPU在圖形操作時可以有SLI速力或者CF交火能力,也有DirectX 提出的多線程渲染技術,但是高并行度的GPU通用計算領域在PC桌面級應用中反倒不能實作多款GPU聯合加速。

  舊版的GPU Direct 1.0主要用于應用程式在網絡間通信,新版的GPU Direct 2.0則轉入節點内通信,支援P2P記憶體通路、傳輸和同步,代碼更少,程式設計效率更高。在此之前,同一節點内的不同GPU互相通路,需要繞道系統記憶體并進行兩次拷貝。就不用理會系統記憶體了,不同GPU可以直接進行傳輸,隻需要一個統一的存儲體系協定NVIDIA就搞定了整個問題。

  說到GPU支援C++程式設計大家一定不會陌生,在Fermi架構釋出之時,C++模闆庫模闆庫就已經被NVIDIA不斷更新。Fermi是首款支援第二代PTX指令的GPU架構,我們知道PTX 2.0使得GPU具備更強的可程式設計性、更精确和提供更高的性能。

Thrust C++模闆化算法與資料結構

  通過上圖可知,Thrust C++模闆化算法與資料結構提供了強大的開源C++并行算法和資料結構。類似C++ STL标準模闆庫;可在編譯時自動選擇最快的代碼路徑,在多核心CPU與GPU之間配置設定工作。

  C/C++語言中所有變量和函數都是通過指針才能确定對象,這樣存在編譯時分離的尋址空間無法确定指針的位置而導緻無法支援C/C++語言。PTX 2.0最為突出的地方在于它提供的統一尋址空間的意義,将GPU當成“共享位址空間”的并行計算機。大量的算法是基于共享位址空間平台的,這樣能夠顯著推動GPU并行計算的發展。

CUDA 4.0引領行業如何發展

  ● CUDA 4.0引領行業如何發展

  2011年2月28日,NVIDIA官方釋出了CUDA 4.0以及全新計算開發包的各項特性,而3月5日NVIDIA正式釋出了GPU通用計算開發包的CUDA 4.0 RC候選版,并提供給開發人員下載下傳使用。

NVIDIA對自己的定位發生變化

  從官方公布的資料看來,NVIDIA的确是早有打算并雄心勃勃進入并行計算市場,目前NVIDIA擁有了從Tegra到Tesla的整套晶片産品線。而這條産品線從節能高效到高性能計算全面涵蓋,這的确是一家處于産業鍊上遊的“超級”計算晶片公司。

  CUDA從釋出開始,到目前已經到了4.0版,從NVIDIA提出CUDA這個概念,已經有将近四年的時間,在最近一年時間CUDA發展迅速,主要是Fermi架構推出之後GPU可程式設計性急劇提升,GPU和CPU的差距已經越來越近,兩者關系也越來越緊密。

CUDA 4個版本發展曆程

  上圖描述了NVIDIA CUDA釋出以來,從1.0版本官方大力宣傳和愛好者嘗試,到2.0版專用領域開始應用CUDA進行程式設計開發,3.0版本已經引來整個行業的關注,大量軟體開始基于CUDA進行基于GPU的加速開發,到今天推出4.0版本繼續降低開發難度提升開發效率。

  除了上述叙述之外,我們通過資料得到CUDA 4.0架構版本還包含大量其它特性與功能,其中包括:

  1、MPI與CUDA應用程式相結合——當應用程式發出MPI收發調用指令時,例如OpenMPI等改編的MPI軟體可通過Infiniband與顯示卡顯存自動收發資料。

  2、GPU多線程共享——多個CPU主線程能夠在一顆GPU上共享運作環境,進而使多線程應用程式共享一顆GPU變得更加輕松。 

  3、單CPU線程共享多GPU——一個CPU主線程可以通路系統内的所有GPU。  開發人員能夠輕而易舉地協調多顆GPU上的工作負荷,滿足應用程式中“halo”交換等任務的需要。

  4、全新的NPP圖像與計算機視覺庫——其中大量圖像變換操作讓開發人員能夠快速開發出成像以及計算機視覺應用程式。

  5、全新、改良的功能

  Visual Profiler中的自動性能分析功能

  Cuda-gdb中的新特性以及新增了對MacOS的支援

  新增了對C++特性的支援,這些特性包括建立/删除以及虛拟等功能

  全新的GPU二進制反彙程式設計式

3大核心提升能否帶來CUDA 4.0飛躍式發展

  目前CUDA能夠有效利用GPU強勁的處理能力和巨大的存儲器帶寬進行圖形渲染以外的計算,廣泛應用于圖像處理、視訊傳播、信号處理、人工智能、模式識别、金融分析、數值計算、石油勘探、天文計算、流體力學、生物計算、分子動力學計算、資料庫管理、編碼加密等領域,并在這些領域中對CPU獲得了一到兩個數量級的加速,取得了令人矚目的成績。