如何在 CUDA 中正确使用全局内存?
How I use global memory correctly in CUDA?
我正在尝试在 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 中声明和复制全局内存?
首先,您需要声明指向将从 CPU 复制到 GPU 的数据的指针。在上面的示例中,我们希望将数组original_cpu_array
复制到 CUDA 全局内存。
int original_cpu_array[array_size];
int *array_cuda;
计算数据将占用的内存大小。
int size = array_size * sizeof(int);
库达内存分配:
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} => %sn",i ,cudaGetErrorString(erros[i]));
}
}
该标志主要用于指示代码中发生错误的部分。例如,在内存分配后:
msg_erro[0] = cudaMalloc((void **)&array_cuda,size);
printErros(msg_erro,msg_erro_size, 0);
我尝试了一些示例,发现如果不传递给全局变量,就不能直接在内核中使用全局变量。即使您在 .cuh 文件中初始化,也需要在 main() 中初始化。
原因:
- 如果全局声明它,则不会在 GPU 全局内存中分配内存。您需要使用
cudaMalloc((void**)&varOne,sizeof(cuComplex))
来分配内存。它只能在 GPU 上分配内存。声明__device__ cuComplex *varOne;
仅用作原型和变量声明。但是,在使用cudaMalloc((void**)&varOne,sizeof(cuComplex))
之前不会分配内存。 - 此外,您最初需要将 main() 中的
*varOne
初始化为 Host 指针。使用cudaMalloc()
后,就会知道指针是设备指针。
步骤顺序是:(对于我测试的代码)
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);
....
}
相关文章:
- OpenCL 将字符从全局内存复制到本地内存
- 为什么CUDA共享内存比瓷砖矩阵乘法中的全局内存慢
- Opencl-将全局内存工作组+边界转移到本地内存
- Cuda-从设备全局内存复制到纹理内存
- 如何在 CUDA 中正确使用全局内存?
- 是通过计算能力1.x的设备中的缓存的全局内存负载/商店
- 全局内存写入在 CUDA 中是否被视为原子写入
- CUDA中更快的是:全局内存写入+__threadfence()或atomicExch()到全局内存
- CUDA 线程在全局内存中的私有位置写入时出现错误结果
- 无法使用 CUDA + MATLAB + Visual Studio 检查全局内存
- CUDA 中的全局内存和纹理有什么区别?
- 调用多个内核,全局内存性能 - CUDA
- 将一系列整数写入全局内存的快速(est)方法
- CUDA:全局内存访问地址
- 简单的加法示例:共享内存版本的reduce执行速度比全局内存慢
- 如何将图像从全局内存复制到openCL的本地内存
- CUDA:将全局内存写入和读取与计算能力同步 1.1
- CUDA全局内存
- 如何将全局内存中的数据安全地加载到 CUDA 中的共享内存中
- 在同一全局内存位置并发写入