簡體   English   中英

我如何在 CUDA 中正確使用全局內存?

[英]How I use global memory correctly in CUDA?

我正在嘗試在 CUDA 中做一個應用程序,它使用用device定義的全局內存。 此變量在 .cuh 文件中聲明。

在另一個 file.cu 中是我的主要文件,我在其中執行 cudaMallocs 和 cudaMemCpy。

那是我的代碼的一部分:

cudaMalloc((void**)&varOne,*tam_varOne * sizeof(cuComplex));
cudaMemcpy(varOne,C_varOne,*tam_varOne * sizeof(cuComplex),cudaMemcpyHostToDevice);

varOne 在 .cuh 文件中聲明如下:

    __device__ cuComplex *varOne;

當我啟動我的內核(我沒有將 varOne 作為參數傳遞)並嘗試使用調試器讀取 varOne 時,它說無法讀取變量。 指針指向它 000..0 所以很明顯它是錯誤的。

那么,我必須如何在 CUDA 中聲明和復制全局內存?

首先,您需要聲明指向將從 CPU 復制到 GPU 的數據的指針。 在上面的示例中,我們要將數組original_cpu_array復制到 CUDA 全局內存。

int original_cpu_array[array_size];   
int *array_cuda;

計算數據將占用的內存大小。

int size = array_size * sizeof(int);

Cuda內存分配:

msg_erro[0] = cudaMalloc((void **)&array_cuda,size);

從 CPU 復制到 GPU:

msg_erro[0] = cudaMemcpy(array_cuda, original_cpu_array,size,cudaMemcpyHostToDevice);

執行內核

從 GPU 復制到 CPU:

msg_erro[0] = cudaMemcpy(original_cpu_array,array_cuda,size,cudaMemcpyDeviceToHost);

空閑內存:

cudaFree(array_cuda);

出於調試原因,通常,我將函數調用的狀態保存在一個數組中。 例如, cudaError_t msg_erro[var]; )。 這不是絕對必要的,但如果在分配和內存傳輸期間發生錯誤,它將為您節省一些時間。

如果確實發生錯誤,我會使用如下函數打印它們:

void printErros(cudaError_t *erros,int size, int flag)
{
 for(int i = 0; i < size; i++)
     if(erros[i] != 0)
     {
         if(flag == 0) printf("Alocacao de memoria");
         if(flag == 1) printf("CPU -> GPU  ");
         if(flag == 2) printf("GPU -> CPU  ");
         printf("{%d} => %s\n",i ,cudaGetErrorString(erros[i]));
     }
}

flag主要是為了指明代碼中發生錯誤的部分。 例如,在內存分配之后:

msg_erro[0] = cudaMalloc((void **)&array_cuda,size);
printErros(msg_erro,msg_erro_size, 0);

我試驗了一些例子,發現你不能直接在內核中使用全局變量而不傳遞給它。 即使您初始化了 in.cuh 文件,您也需要在 main() 中進行初始化。

原因:

  1. 如果在全局聲明,Memory 不會分配到 GPU Global Memory 中。 您需要使用cudaMalloc((void**)&varOne,sizeof(cuComplex))來分配內存。 它只能在 GPU 上分配內存。 聲明__device__ cuComplex *varOne; 就像原型和變量聲明一樣工作。 但是,在使用cudaMalloc((void**)&varOne,sizeof(cuComplex))之前不會分配內存。
  2. 此外,您需要首先將 main() 中的*varOne初始化為主機指針。 使用cudaMalloc()后,得知該指針為 Device Pointer。

步驟的順序是:(對於我測試的代碼)

int *Ad;        //If you can allocate this in .cuh file, you dont need the shown code in main()

__global__ void Kernel(int *Ad){
....
}

int main(){
....
      int size=100*sizeof(int);
      cudaMalloc((void**)&Ad,size);
      cudaMemcpy(Ad,A,size,cudaMemcpyHostToDevice);
....
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM