主机内存指在CPU上运行的代码所使用的内存,正常C/C++代码中的使用的变量,无论是在堆还是栈上,使用的都是主机内存。
使用设备内存指在GPU上运行的代码可以使用到的内存。
需要注意的是,核函数和device函数中是不能访问和读取主机内存的。这意味着,在调用核函数时,将数据(主机内存)指针当作参数传入核函数,在核函数中是无法读取到数据的,因为参数的指针指向的是主机内存的地址,而在核函数中读写会被当做设备内存来解析。
因此需要掌握在CPU代码中如何管理设备内存的方法。
__host__ cudaError_t cudaMalloc(void **devPtr, size_t size);
__host__ cudaError_t cudaFree(void *devPtr);
CUDA提供cudaMalloc 和 cudaFree 来管理设备内存的申请和释放,用法与C语言中的malloc 和 free相似,只是传递数据的方式不同。
使用时需要注意cudaMalloc 的第一个参数是一个二级指针,所以传参的时候一定要注意。
int *arry = 0;
int arrySize = 100;
//申请一个长度为100的int数组
cudaMalloc((void**)&arry, size * sizeof(int));
//释放内存
cudaFree(arry);
如上述代码,完成了一个int数组的内存的申请与释放。
上文提到,在核函数中无法读写主机内存中的数据,那么同理,在CPU上运行的代码,也无法读写在设备内存中的数据。
但是在实际应用场景中,一定会需要到两边数据的交互,那么怎么实现?
CUDA提供了数据拷贝函数,以供CPU操作设备内存的数据。
__host__ cudaError_t cudaMemcpy(void *dst, const void *src, size_t count, enum cudaMemcpyKind kind);
dst: 要拷贝到的目标地址
src: 要拷贝的源地址
count:要拷贝的长度,单位是字节。
kind:拷贝数据的方式。
cudaMencpykind的定义是: