【平行運算】CUDA教學(一) 概念介紹 - 都會阿嬤

文章推薦指數: 80 %
投票人數:10人

都會阿嬤- 現在大部份做深度學習的工程師視CUDA、GPU加速為黑盒子, ... 在CUDA 中,最基本的運算單元是thread,很多thread 組成一個block,很多block 組成一個gird ... Skiptocontent 觀看次數: 9,457 現在大部份做深度學習的工程師視CUDA、GPU加速為黑盒子,但若你能了解CUDA,這就是你比90%的人還要厲害的關鍵。

CUDA(ComputeUnifiedDeviceArchitecture,統一計算架構)是NVIDIA研發的平行運算平台及編程模型,可利用繪圖處理單元(GPU)的能力大幅提升運算效能。

目前最流行的深度學習,在訓練類神經網路時因為牽涉到大量的運算,也是使用CUDA等平行運算技術來進行加速。

目前主流的Tensorflow、Pytorch等深度學習框架也大量了使用CUDA。

也正是因為GPU的運算效能,才讓深度學習可以有今天的表現。

因此了解GPU、CUDA、平行運算的技術是非常重要的! 1.CUDA平行加速工作流程 在host(CPU)配置記憶體並初始化資料在device(GPU)配置記憶體將資料從host傳送到device(CPU->GPU)在GPU上執行核心程式碼(Kernel)將資料從device傳送回host(GPU->CPU) 上面提到了幾個關鍵字:配置記憶體、資料傳輸、核心程式碼Kernel,以下將一一詳細介紹 2.配置記憶體 記憶體的配置是相當簡單,在CPU上使用malloc(memoryallocation)來配置記憶體,在GPU使用cudaMalloc(cudamemoryallocation)來配置記憶體。

CPU記憶體: mallocfree float*Array_CPU; Array_CPU=(float*)malloc(Array_Size); free(Array_CPU); GPU記憶體: cudaMalloccudaFree float*Array_GPU; cudaMalloc(&Array_GPU,Array_Size); cudaFree(Array_GPU); 3.資料傳輸 無論是從CPU到GPU都是cudaMemcpy這個函式,只需要傳入cudaMemcpyHostToDevice或cudaMemcpyDeviceToHost即可指定是將資料從哪裡複製到哪裡 CPU到GPU(HosttoDevice): cudaMemcpy()cudaMemcpyHostToDevice cudaMemcpy(Array_GPU,Array_CPU,Array_Size,cudaMemcpyHostToDevice) GPU到CPU(DevicetoHost): cudaMemcpy()cudaMemcpyDeviceToHost cudaMemcpy(Array_CPU,Array_GPU,Array_Size,cudaMemcpyDeviceToHost) 4.核心程式碼(Kernel) CUDA讓我們可以自己定義核心程式碼(kernel),當他被呼叫的時候,會被每個thread都執行一次,N個thread執行N次Kernelfunction在定義時要使用globalKernelfunction在呼叫時要使用<<>>並指定block數目,和每個block裡面有多少threads GPU_Kernel<<>>(N,Array_GPU); 以下的程式碼用了1個block,N個threads來執行向量的加法,向量A+向量B並存至C //Kerneldefinition __global__voidVecAdd(float*A,float*B,float*C) { inti=threadIdx.x; C[i]=A[i]+B[i]; } intmain() { ... //KernelinvocationwithNthreads VecAdd<<<1,N>>>(A,B,C); ... } 5.執行緒層級(ThreadHierachy) 在CUDA中,最基本的運算單元是thread,很多thread組成一個block,很多block組成一個gird(block也可以稱作threadblock,由thread組成的block) 所以由大到小是: GridBlockThread GBT、GBT、GBT(幫助記憶) 要知道每一個thread獨特的座標以指派運算任務,我們會需要block的index和thread的index。

這些index可以是1D、2D或3D,想像成三維座標就可以了要知道每一個thread獨特的座標以指派運算任務,我們會需要block的大小。

假設一個block裡面有4x3的threads(像上圖),則blockDim.x=4,blockDim.y=3 //在一個grid裡面,一個thread的座標(x,y)為: x=blockDim.x*blockIdx.x+threadIdx.x y=blockDim.y*blockIdx.y+threadIdx.y 以下這張圖很清楚的介紹了在1D的情況下,thread_id的計算方式:(圖片來源:AnEvenEasierIntroductiontoCUDA) 以下的程式碼執行了矩陣的加法,使用了大小為16x16的block(每個block裡有256個thread),並且使用了numBlcoks個block,這邊block的數目為動態計算,可以針對給訂的資料來決定要使用多少個block //Kerneldefinition __global__voidMatAdd(floatA[N][N],floatB[N][N], floatC[N][N]) { inti=blockIdx.x*blockDim.x+threadIdx.x; intj=blockIdx.y*blockDim.y+threadIdx.y; if(i>>(A,B,C); ... } 詳細的Index、Dimension等觀念可以參考ProgrammingGuide::CUDAToolkitDocumentation因為blockDim*blockIdx+threadIdx很常用,所以建議可以記起來 6.參考資料 ProgrammingGuide::CUDAToolkitDocumentationAnEvenEasierIntroductiontoCUDA cuda,平行計算,計算機 Grandma ViewallpostsbyGrandma→ Postnavigation Olderpost【量子計算】IBMQiskit教學part2:設計第一個量子電路Newerpost【PyTorch內部機制】Tensor,Storage,Strides張量如何存放在記憶體上? Youmightalsolike 留言討論區 取消回覆 最熱門的文章 Python股票分析:Stocker強大的股價預測分析工具(附完整程式碼)(36,072) TensorFlow2教學:Keras–MNIST–數字辨識(29,391) Linux教學:chmod指令(28,469) TensorFlow2教學:TensorFlow2總覽、介紹(28,070) Python教學:AnacondaNavigator(26,859) 科技新聞【科技新聞】為什麼很難買到好用的東西?2022年3月19日 【科技新聞】美國參議院一致投票決定將夏令時永久化2022年3月16日 【科技新聞】Earn-IT威脅到加密和用戶自由2022年3月13日 標籤cuda(1) html(1) javascript(1) Keras(4) latex(7) Linux指令(9) MNIST(4) openmp(4) openmpi(2) p5.js(1) Processing(1) Python(9) pytorch(1) qiskit(2) react.js(1) SQL(4) Tensorflow2(7) Web(3) Youtube(1) 上下界變換(1) 台大(1) 向量(1) 平行計算(7) 廣告(1) 架站(1) 波動方程式(1) 深度學習(12) 演算法(1) 爬蟲(3) 物理(2) 研究所(1) 碰撞(1) 積分技巧(3) 考古題(1) 股票分析(3) 自然語言生成(1) 航空(1) 解答(1) 計算機(9) 語音合成(3) 量子力學(2) 量子電腦(2) 雙振子(1) 電磁學(1) 飛行(1)



請為這篇文章評分?