CUDA内存初始化小记

步子跨得太大,内存分配的事情有点糊涂,梳理一下。
我们直到CUDA运算时候基本分为:

  1. host数据初始化
  2. device分配内存
  3. 把host数据赋值到device上
  4. 进行CUDA kernel运算
  5. 把CUDA运算结果写回到host上

基本上就这几步,但是这中间的内存操作其实还蛮多细节。
我们拿一个简单的程序举例:

#include<stdio.h>

__global__ void add(const double *x,const double *y,const double *z,int size){
	
}
int main(){
	int N = 1000;
	int M = N*sizeof(double);
	double *h_x = (double*)malloc(N);
	double *h_y = (double*)malloc(N);
	double *h_z = (double*)malloc(N);
	for(int i = 0;i < N;i++){
		h_x[i] = rand() % 2;
		h_y[i] = rand() % 2;
	}

在这里插入图片描述

这是第一部分,可以看到我们已经把host的数据初始化了。接下来的操作我们需要把这些数据转移到CUDA上。转移到CUDA上得需要变量呢,所以继续初始化

double *d_x,*d_y,*d_z;
cudaMalloc((void**)&d_x,M);
cudaMalloc((void**)&d_y,M);
cudaMalloc((void**)&d_z,M);

到这里为止,CPU上的d_x,d_y,d_z的值是GPU上的三个大小为M的内存地址。其中cudaMalloc的函数说明如下:

cudaError_t cudaMalloc(void **address,size_t size);

在这里插入图片描述

可以看到第一个参数就是指针的指针,也就是指针的地址。所以我们这里给d_x,d_yd_z在加一个&来表示指针的地址,其中前面的void**表示强制类型转换。
所以cudaMalloc(void **address,size_t size)的作用就是在Device上开辟一段大小为size的内存空间,然后将这个内存空间的地址赋值给address。清楚了这些后,就知道我们上面在device上开辟的是M大小的内存空间。接下来我们需要把这个GPU中M大小的内存空间的值填满元素,然后计算得到结果呀:

把h_x所指向的值复制到d_x所指的内存空间(GPU上的内存空间)
cudaMemcpy(d_x,h_x,M,cudaMemcpyHostToDevice);
cudaMemcpy(d_y,h_y,M,cudaMemcpyHostToDevice);
add<<<1,N>>>(d_x,d_y,d_z,N);


在这里插入图片描述

这个也显而易见,cudaMemcpy是把h_x所指的内存空间值直接赋值给d_x,d_y所值的内存空间值,这样的话CPU的数据就迁移到GPU数据上了。然后我们调用CUDA kernel核进行计算add<<<>>>,计算结果存放到d_z所指的内存空间中。我们还需要把d_z所指内容复制到h_z完成CUDA的一套流程:‘

cudaMemcpy(h_z,d_z,M,cudaMemcpyDeviceToHost);

最后记得free掉我们之前malloc的内存

free(h_x);
free(h_y);
free(h_z);
cudaFree(d_x);
cudaFree(d_y);
cudaFree(d_z);
return 0;

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值