Cuda 學習 - 基本定義 === # Cuda 的資料使用流程如下 1. 從 CPU 做資料初始化 2. 將資料從 CPU 搬運至 GPU 3. Kernel 根據 Grid、Block 大小做資源分配 4. 將執行完的資料從 GPU 搬運回 CPU 5. 回收 CPU、GPU 的相關資源 # 名詞定義 * 程式上 * Host code : 在 CPU 上執行的程式 * Device code : 在 GPU 上執行的程式 * ```__global__```:在 GPU 上執行,由 CPU 呼叫,無返回值。 * ```__device__```:在 GPU 上執行,由其他 GPU 函數呼叫,可有返回值。 * ```__host__```:在 CPU 上執行,由 CPU 呼叫,可有返回值。 * 相關 element * Thread * 執行 GPU 運算的最小單位, 同常由 block 來分配須使用的 thread 數量 * 每個 thread 可以是 1~3 維, 視目標任務而定 * 可透過 threadIDx 來進行識別 * Block * Block 低下含有若干個 thread, 並且由 grid 來分配須使用的 block 數量 * 在 Block 底下的 Thread 可共享記憶體, 每個 block可透過 blockIDx進行識別 * 每個 block 可以是 1~3 維, 視目標任務而定 * Grid * 由多個 Block 組合而成根據任務分配 Block 所需的數量, 為用來啟動kernel function的最高級別 * 每個 grid 可以是 1~3 維, 視目標任務而定, 可透過 gridDim 來查詢維度大小 ![image](https://hackmd.io/_uploads/BkBDotc2C.png) # 程式上的設置及範例 * ```kernel_name<<<num_of_block, thread_per_block>>>(argument)``` * kernel_name : 是我們要執行的 cuda 程式 * num_of_block : block 設定的數量 * thread_per_block : 每個 block 需要的thread * num_of_block 跟 thread_per_block 均為 dim3 的變數, 識任務情況資料維度為1~3維 * 範例 * 在以下範里中我們設定了以下 * grid 含有2個 block * 每個block 含有4個 thread * 備註 : dim3可彈性的設定 例如 dim3 a(4)、b(2,5)、c(2,5,4) * 將 grid 及 block 的設定帶入並啟用 kernel function -> hello_cuda_with_id * 最後會輸出是由哪個 blockIDx 及 threadIDx 打印 Hello World ```cpp= #include <cuda_runtime.h> #include <device_launch_parameters.h> #include <stdio.h> __global__ void hello_cuda(){ printf("Hello CUDA world \n"); } __global__ void hello_cuda_with_id(){ printf("Hello CUDA world with blockIDx.x %d, threadIDx %d \n", blockIdx.x, threadIdx.x); } int main(){ dim3 grid(2); // Set up the block size in a grid dim3 block(4); // set up the thread size in a block hello_cuda_with_id<<<grid, block>>>(); cudaDeviceSynchronize(); cudaDeviceReset(); return 0; } ``` ![image](https://hackmd.io/_uploads/H1U3QdYn0.png) * ###### tags : `Cuda`