在CUDA如何使用二維數組(**[M][N])

總有些童鞋想知道怎麼在CUDA中使用二維數組([M][N]這種類型),其實這個很簡單,不過你要完全弄明白,必須對指針,地址等概念非常清楚才行。寫這篇博客解決下大家這個問題:

1、首先講述一下在一般C語言中如何使用二維數組。

  1. int r, c;  
  2. int **arr = (int**)malloc(ROWS*sizeof(int*));  
  3. int *data = (int*)malloc(COLS*ROWS*sizeof(int));  
  4. for (r = 0; r < ROWS; r++)  
  5. {  
  6.     arr[r] = data + r*COLS;  
  7. }  
  8.   
  9. free(arr);  
  10. free(data);  

    代碼中的arr實個二維數組變量了,你可以在for循環之後arr[i][j]的方式使用它。

 

2、告訴你如何在CUDA中使用二維數組可以類比1中的方法,不過你要清楚幾點,這幾點在代碼之後說明。


  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <cuda_runtime.h>  
  4.   
  5. #define ROWS 32  
  6. #define COLS 16  
  7. #define CHECK(res) if(res!=cudaSuccess){exit(-1);}  
  8. __global__ void Kerneltest(int **da, unsigned int rows, unsigned int cols)  
  9. {  
  10.     unsigned int row = blockDim.y*blockIdx.y + threadIdx.y;  
  11.     unsigned int col = blockDim.x*blockIdx.x + threadIdx.x;  
  12.     if (row < rows && col < cols)  
  13.     {  
  14.         da[row][col] = row*cols + col;  
  15.     }  
  16. }  
  17.   
  18. int main(int argc, char **argv)  
  19. {  
  20.     int **da = NULL;  
  21.     int **ha = NULL;  
  22.     int *dc = NULL;  
  23.     int *hc = NULL;  
  24.     cudaError_t res;  
  25.     int r, c;  
  26.     bool is_right=true;  
  27.   
  28.     res = cudaMalloc((void**)(&da), ROWS*sizeof(int*));CHECK(res)  
  29.     res = cudaMalloc((void**)(&dc), ROWS*COLS*sizeof(int));CHECK(res)  
  30.     ha = (int**)malloc(ROWS*sizeof(int*));  
  31.     hc = (int*)malloc(ROWS*COLS*sizeof(int));  
  32.   
  33.     for (r = 0; r < ROWS; r++)  
  34.     {  
  35.         ha[r] = dc + r*COLS;  
  36.     }  
  37.     res = cudaMemcpy((void*)(da), (void*)(ha), ROWS*sizeof(int*), cudaMemcpyHostToDevice);CHECK(res)  
  38.     dim3 dimBlock(16,16);  
  39.     dim3 dimGrid((COLS+dimBlock.x-1)/(dimBlock.x), (ROWS+dimBlock.y-1)/(dimBlock.y));  
  40.     Kerneltest<<<dimGrid, dimBlock>>>(da, ROWS, COLS);  
  41.     res = cudaMemcpy((void*)(hc), (void*)(dc), ROWS*COLS*sizeof(int), cudaMemcpyDeviceToHost);CHECK(res)  
  42.   
  43.     for (r = 0; r < ROWS; r++)  
  44.     {  
  45.         for (c = 0; c < COLS; c++)  
  46.         {  
  47.             printf("%4d ", hc[r*COLS+c]);  
  48.             if (hc[r*COLS+c] != (r*COLS+c))  
  49.             {  
  50.                 is_right = false;  
  51.             }  
  52.         }  
  53.         printf("\n");  
  54.     }  
  55.     printf("the result is %s!\n", is_right? "right":"false");  
  56.     cudaFree((void*)da);  
  57.     cudaFree((void*)dc);  
  58.     free(ha);  
  59.     free(hc);  
  60.     getchar();  
  61.     return 0;  
  62. }  

在CUDA中使用二維數組的幾點說明:

1)da是一個二維變量,一定更不可以在33行的時候把ha改成da!一定要記住顯存和內存是相互獨立的,主機端的程序不可以直接操作顯存!必須通過CUDA 提供的API函數來操作!

2)注意在內存申請時強制類型轉換(void**)(&),怎麼把***的變量轉成**了!!這主要是API藉口決定的,最好自己顯式轉換格式,避免不必要的麻煩。

3)看見數據拷貝的函數了嗎,類型、類型、還是類型。

4)別忘了釋放內存和顯存!看見沒,還是類型。

5)很希望這篇博客能幫到大家,可是我真的不推薦大家在GPU上使用二維數組!真的!!爲什麼呢?終歸是效率惹的禍!顯存的訪問總是慢的。二維訪存,可是連續訪問了兩次啊。要是老這樣做,不但執行效率低,而且寫代碼也慢。如果對內存的概念不熟悉,千萬別趟這趟渾水。看懂這段代碼,就當是學習一下或者理解下內存、顯存與內存獨立的概念和規則吧。

附上執行結果:


 

轉自:http://blog.csdn.net/bendanban/article/details/7669624

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章