CUDA学习笔记
CUDA學(xué)習(xí)筆記
目錄
CUDA學(xué)習(xí)筆記
函數(shù)類型限定符
__global__
__host__
__device__
變量類型限定符
__device__
__constant__
CUDA線程概念
網(wǎng)格(Grid)、線程塊(Block)和線程(Thread)的組織關(guān)系
線程索引的計(jì)算公式
dim3結(jié)構(gòu)類型
函數(shù)類型限定符
__global__
表示一個(gè)內(nèi)核函數(shù),主機(jī)(CPU)上調(diào)用,但在設(shè)備(GPU)上執(zhí)行
__host__
由CPU調(diào)用,且在CPU執(zhí)行的函數(shù),默認(rèn)的函數(shù)限定符
__device__
設(shè)備執(zhí)行的程序,device前綴定義的函數(shù)只能在GPU上執(zhí)行,所以device修飾的函數(shù)里面不能調(diào)用一般常見(jiàn)的函數(shù)
變量類型限定符
__device__
?
__shared__
?
__constant__
?
CUDA線程概念
CUDA線程的概念與CPU的概念基本一致:進(jìn)程是系統(tǒng)資源分配的基本單位, 而線程是CPU 能調(diào)度和獨(dú)立運(yùn)行的基本單位(最小單元)
網(wǎng)格(Grid)、線程塊(Block)和線程(Thread)的組織關(guān)系
https://blog.csdn.net/gqixf/article/details/80760701?
多個(gè)線程thread組成一個(gè)block,多個(gè)block組成一個(gè)grid.
CUDA的軟件架構(gòu)由網(wǎng)格(Grid)、線程塊(Block)和線程(Thread)組成,相當(dāng)于把GPU上的計(jì)算單元分為若干(2~3)個(gè)網(wǎng)格,每個(gè)網(wǎng)格內(nèi)包含若干(65535)個(gè)線程塊,每個(gè)線程塊包含若干(512)個(gè)線程,三者的關(guān)系如下圖:
Thread,block,grid是CUDA編程上的概念,為了方便程序員軟件設(shè)計(jì),組織線程。
- thread:一個(gè)CUDA的并行程序會(huì)被以許多個(gè)threads來(lái)執(zhí)行
- block:數(shù)個(gè)threads會(huì)被群組成一個(gè)block,同一個(gè)block中的threads可以同步,也可以通過(guò)shared memory通信?
- grid:多個(gè)blocks則會(huì)再構(gòu)成grid
線程索引的計(jì)算公式
一個(gè)Grid可以包含多個(gè)Blocks,Blocks的組織方式可以是一維的,二維或者三維的。block包含多個(gè)Threads,這些Threads的組織方式也可以是一維,二維或者三維的。
CUDA中每一個(gè)線程都有一個(gè)唯一的標(biāo)識(shí)ID—ThreadIdx,這個(gè)ID隨著Grid和Block的劃分方式的不同而變化,這里給出Grid和Block不同劃分方式下線程索引ID的計(jì)算公式。
1、 grid劃分成1維,block劃分為1維
? ? int threadId = blockIdx.x *blockDim.x + threadIdx.x; ?
2、 grid劃分成1維,block劃分為2維 ?
? ? int threadId = blockIdx.x * blockDim.x * blockDim.y+ threadIdx.y * blockDim.x + threadIdx.x; ?
3、 grid劃分成1維,block劃分為3維 ?
? ? int threadId = blockIdx.x * blockDim.x * blockDim.y * blockDim.z ?
? ? ? ? ? ? ? ? ? ? ? ?+ threadIdx.z * blockDim.y * blockDim.x ?
? ? ? ? ? ? ? ? ? ? ? ?+ threadIdx.y * blockDim.x + threadIdx.x; ?
4、 grid劃分成2維,block劃分為1維 ?
? ? int blockId = blockIdx.y * gridDim.x + blockIdx.x; ?
? ? int threadId = blockId * blockDim.x + threadIdx.x; ?
5、 grid劃分成2維,block劃分為2維?
? ? int blockId = blockIdx.x + blockIdx.y * gridDim.x; ?
? ? int threadId = blockId * (blockDim.x * blockDim.y) ?
? ? ? ? ? ? ? ? ? ? ? ?+ (threadIdx.y * blockDim.x) + threadIdx.x; ?
6、 grid劃分成2維,block劃分為3維
? ? int blockId = blockIdx.x + blockIdx.y * gridDim.x; ?
? ? int threadId = blockId * (blockDim.x * blockDim.y * blockDim.z) ?
? ? ? ? ? ? ? ? ? ? ? ?+ (threadIdx.z * (blockDim.x * blockDim.y)) ?
? ? ? ? ? ? ? ? ? ? ? ?+ (threadIdx.y * blockDim.x) + threadIdx.x; ?
7、 grid劃分成3維,block劃分為1維?
? ? int blockId = blockIdx.x + blockIdx.y * gridDim.x ?
? ? ? ? ? ? ? ? ? ? ?+ gridDim.x * gridDim.y * blockIdx.z; ?
? ? int threadId = blockId * blockDim.x + threadIdx.x; ?
8、 grid劃分成3維,block劃分為2維 ?
? ? int blockId = blockIdx.x + blockIdx.y * gridDim.x ?
? ? ? ? ? ? ? ? ? ? ?+ gridDim.x * gridDim.y * blockIdx.z; ?
? ? int threadId = blockId * (blockDim.x * blockDim.y) ?
? ? ? ? ? ? ? ? ? ? ? ?+ (threadIdx.y * blockDim.x) + threadIdx.x; ?
9、 grid劃分成3維,block劃分為3維
? ? int blockId = blockIdx.x + blockIdx.y * gridDim.x ?
? ? ? ? ? ? ? ? ? ? ?+ gridDim.x * gridDim.y * blockIdx.z; ?
? ? int threadId = blockId * (blockDim.x * blockDim.y * blockDim.z) ?
? ? ? ? ? ? ? ? ? ? ? ?+ (threadIdx.z * (blockDim.x * blockDim.y)) ?
? ? ? ? ? ? ? ? ? ? ? ?+ (threadIdx.y * blockDim.x) + threadIdx.x;? ??
dim3數(shù)據(jù)結(jié)構(gòu)
dim3是CUDA 中一個(gè)比較特殊的數(shù)據(jù)結(jié)構(gòu),我們可以用這個(gè)數(shù)據(jù)結(jié)構(gòu)創(chuàng)建一個(gè)二維的線程塊與線程網(wǎng)格。例如在長(zhǎng)方形布局的方式中,每個(gè)線程塊的X 軸方向上開(kāi)啟了32 個(gè)線程, Y軸方向上開(kāi)啟了4 個(gè)線程。在線程網(wǎng)格上, X 軸方向上有1 個(gè)線程塊, Y 軸方向有4 個(gè)線程塊。
dim3 threads_rect(32,4) dim3 blocks_rect(1,4)dim3 ? ?blocks(DIM/16,DIM/16);
dim3 ? ?threads(16,16);
kernel<<<blocks,threads>>>( d->dev_bitmap, ticks );
?
?
?
?
?
總結(jié)
- 上一篇: python实现交并比IOU
- 下一篇: Python OpenCV实现鼠标画框