CUDA C不是C語言,而是對C語言進行擴充。
CUDA對C的擴充主要包括以下四個方面: 函數類型限定符,用來確定函數是在CPU還是在GPU上執行,以及這個函數是從CPU調用還是從GPU調用。
__device__,__device__表示從GPU上調用,在GPU上執行;
__global__,__global__表示在CPU上調用,在GPU上執行,也就是所謂的核心(kernel)函數;核心主要用來執行多線程調用。
__host__,__host__表明在CPU上調用,在CPU上執行,這是預設時的情況,也就是傳統的C函數。
CUDA支援__host__和__device__的聯用,表示同時為主機和裝置編譯。
此時這個函數不能出現多線程語句。
變數類型限定符,用來規定變數儲存什麼位置上。
在傳統的CPU程式上,這個任務由編譯器承擔。在CUDA中,不僅要使用主機端的記憶體,還要使用裝置端的顯存和GPU片上的寄存器、共用儲存空間和緩衝。
在CUDA儲存空間模型中,一共抽象出來了8種不同的儲存空間。複雜的儲存空間模型使得必須要使用限定符要說明變數的儲存位置。
(注意,上面的那個是函數的類型限定,現在這個是變數的限定)
__device__,__device__表明聲明的資料存放在顯存中,所有的線程都可以訪問,而且主機也可以通過執行階段程式庫訪問;
__shared__,__shared__表示資料存放在共用儲存空間在,只有在所在的塊內的線程可以訪問,其它塊內的線程不能訪問;
__constant__,__constant__表明資料存放在常量儲存空間中,可以被所有的線程訪問,也可以被主機通過執行階段程式庫訪問;
texture,texture表明其繫結資料可以被紋理緩衝加速存取,其實資料本身的存放位置並沒有改變,
紋理是來源於圖形學的一介概念,CUDA使用它的原因一部分在於支援圖形處理,另一方面也可以利用它的一些特殊功能。
如果在GPU上執行的函數內部的變數沒有限定符,那表示它存放在寄存器或者本機存放區器中,在寄存器中的資料只歸線程所有,其它線程不可見。 如果SM的寄存器用完,那麼編譯器就會將本應放到寄存器中的變數放到本機存放區器中。
執行配置運算子<<< >>>,用來傳遞核心功能的執行參數。
執行配置有四個參數:
第一個參數聲明網格的大小,
第二個參數聲明塊的大小,
第三個參數聲明動態分配的共用儲存空間大小,預設為0,
最後一個參數聲明執行的流,預設為0。
五個內建變數,用於在運行時獲得網格和塊的尺寸及線程索引等資訊 gridDim, gridDim是一個包含三個元素x,y,z的結構體,分別表示網格在x,y,z三個方向上的尺寸,雖然其有三維,但是目前只能使用二維;
blockDim, blockDim也是一個包含三個元素x,y,z的結構體,分別表示塊在x,y,z三個方向上的尺寸,對應於執行配置中的第一個參數,對應於執行配置的第二個參數; blockIdx, blockIdx也是一個包含三個元素x,y,z的結構體,分別表示當前線程所在塊在網格中x,y,z三個方向上的索引; threadIdx, threadIdx也是一個包含三個元素x,y,z的結構體,分別表示當前線程在其所在塊中x,y,z三個方向上的索引;
warpSize,warpSize表明warp的尺寸,在計算能力為1.0的裝置中,這個值是24,在1.0以上的裝置中,這個值是32。 其它的還有數學函數,原子函數,紋理讀取、綁定函數,內建柵欄,記憶體fence函數等。
一般而言,知道這些就應該能夠寫出CUDA程式了,當然要寫好的話,必須知道很多其它的細節。
因為我對作業系統瞭解得不是很細,然後下面是補充的一些知識。
這裡的核心功能是指,系統調用函數,就是API介面,讓處於使用者態的我們能夠向作業系統發出函數調用請求
線程:
我對於線程,進程的概念一直都是比較模糊,最近整理了一下。總結起來就是,線程是進程的一部分,進程是程式的一部分。
線程的引入:例如,有一個Web伺服器要進程的方式並發地處理來自不同使用者的網頁訪問請求的話,可以建立父進程和多個子進程的方式來進行處理,但是建立一個進程要花費較大的系統開銷和佔用較多的資源。除外,這些不同的使用者子進程在執行的時候涉及到進程環境切換,環境切換是一個複雜的過程。所以,為了減少進程切換和建立的開銷,提高執行效率和節省資源,人們在作業系統中引入了"線程(thread)"的概念。
進程的作用和定義:進程是為了提高CPU的執行效率,減少因為程式等待帶來的CPU空轉以及其他電腦軟硬體資源的浪費而提出來的。進程是為了完成使用者任務所需要的程式的一次執行過程和為其分配資源的一個基本單位,是一個具有獨立功能的程式段對某個資料集的一次執行活動。
線程和進程的區別:
1、線程是進程的一部分,所以線程有的時候被稱為是輕權進程或者輕量級進程。
2、一個沒有線程的進程是可以被看作單線程的,如果一個進程內擁有多個進程,進程的執行過程不是一條線(線程)的,而是多條線(線程)共同完成的。
3、系統在啟動並執行時候會為每個進程分配不同的記憶體地區,但是不會為線程分配記憶體(線程所使用的資源是它所屬的進程的資源),線程組只能共用資源。那就是說,出了CPU之外(線程在啟動並執行時候要佔用CPU資源),電腦內部的軟硬體資源的分配與線程無關,線程只能共用它所屬進程的資源。
4、與進程的控製表PCB相似,線程也有自己的控製表TCB,但是TCB中所儲存的線程狀態比PCB表中少多了。
5、進程是系統所有資源分派時候的一個基本單位,擁有一個完整的虛擬空間地址,並不依賴線程而獨立存在。
進程與程式的區別:
程式是一組指令的集合,它是靜態實體,沒有執行的含義。而進程是一個動態實體,有自己的生命週期。一般說來,一個進程肯定與一個程式相對應,並且只有一個,但是一個程式可以有多個進程,
或者一個進程都沒有
也可以只有一個進程。除此之外,進程還有並發性和交往性。簡單地說,進程是程式的一部分,程式啟動並執行時候會產生進程。
總結:
線程是進程的一部分,進程是程式的一部分。