CUDA学习笔记
CUDA學習筆記
目錄
CUDA學習筆記
函數類型限定符
__global__
__host__
__device__
變量類型限定符
__device__
__constant__
CUDA線程概念
網格(Grid)、線程塊(Block)和線程(Thread)的組織關系
線程索引的計算公式
dim3結構類型
函數類型限定符
__global__
表示一個內核函數,主機(CPU)上調用,但在設備(GPU)上執行
__host__
由CPU調用,且在CPU執行的函數,默認的函數限定符
__device__
設備執行的程序,device前綴定義的函數只能在GPU上執行,所以device修飾的函數里面不能調用一般常見的函數
變量類型限定符
__device__
?
__shared__
?
__constant__
?
CUDA線程概念
CUDA線程的概念與CPU的概念基本一致:進程是系統資源分配的基本單位, 而線程是CPU 能調度和獨立運行的基本單位(最小單元)
網格(Grid)、線程塊(Block)和線程(Thread)的組織關系
https://blog.csdn.net/gqixf/article/details/80760701?
多個線程thread組成一個block,多個block組成一個grid.
CUDA的軟件架構由網格(Grid)、線程塊(Block)和線程(Thread)組成,相當于把GPU上的計算單元分為若干(2~3)個網格,每個網格內包含若干(65535)個線程塊,每個線程塊包含若干(512)個線程,三者的關系如下圖:
Thread,block,grid是CUDA編程上的概念,為了方便程序員軟件設計,組織線程。
- thread:一個CUDA的并行程序會被以許多個threads來執行
- block:數個threads會被群組成一個block,同一個block中的threads可以同步,也可以通過shared memory通信?
- grid:多個blocks則會再構成grid
線程索引的計算公式
一個Grid可以包含多個Blocks,Blocks的組織方式可以是一維的,二維或者三維的。block包含多個Threads,這些Threads的組織方式也可以是一維,二維或者三維的。
CUDA中每一個線程都有一個唯一的標識ID—ThreadIdx,這個ID隨著Grid和Block的劃分方式的不同而變化,這里給出Grid和Block不同劃分方式下線程索引ID的計算公式。
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數據結構
dim3是CUDA 中一個比較特殊的數據結構,我們可以用這個數據結構創建一個二維的線程塊與線程網格。例如在長方形布局的方式中,每個線程塊的X 軸方向上開啟了32 個線程, Y軸方向上開啟了4 個線程。在線程網格上, X 軸方向上有1 個線程塊, Y 軸方向有4 個線程塊。
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 );
?
?
?
?
?
總結
- 上一篇: python实现交并比IOU
- 下一篇: 使用tf.keras搭建mnist手写数