我如何在CUDA中正确使用全局内存?

时间:2012-11-07 17:39:47

标签: c++ c memory-management cuda gpu

我正在尝试在CUDA中使用设备定义的全局内存。 此变量在.cuh文件中声明。

在另一个文件中.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中声明和复制全局内存?

2 个答案:

答案 0 :(得分:2)

您必须首先定义将保存将复制到CUDA的数据的指针: 在上面的示例中,我们将数组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]));
     }
}

该标志主要用于指示代码中发生错误的部分。例如,在内存分配之后:

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

答案 1 :(得分:0)

我已经尝试了一些例子,发现你不能直接在内核中使用全局变量而不传递给它。即使您在.cuh文件中初始化,也需要在main()中初始化。

原因:

  1. 如果您全局声明,则不会在GPU全局内存中分配内存。您需要使用cudaMalloc((void**)&varOne,sizeof(cuComplex))来分配内存。它只能在GPU上分配内存。声明__device__ cuComplex *varOne;就像原型和变量声明一样。但是,在使用cudaMalloc((void**)&varOne,sizeof(cuComplex))之前,不会分配内存。
  2. 此外,您需要最初将main()中的*varOne初始化为Host指针。使用cudaMalloc()后,它会知道指针是设备指针。
  3. 步骤顺序为:(对于我测试过的代码)

    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);
    ....
    }