如何理解cudaMalloc()

之前没怎么用指针,就很少去搞清楚指针取址这些的内涵。导致现在用起来很费劲,就去补一补之前的知识

1.指针、引用、取址的区别

1.1定义时的*和&

指针*

类型名 *var

int *point; //  表示point是指针,指向int型变量

&作引用的关键字

类型名 & 别名 = var;

int &b=var; //表示b是引用,为var的别名,对b的所有操作等同于对var的操作·

指针和引用的区别

指针可以为空,引用不能为空

1.2使用时的*和&

  • *在使用时表示取内容。
  • &在使用时表示取地址。

程序示例

#include<iostream>

using namespace std;

int main(){
    int a=1;
    int &c=a;  //c是a的别名
    int *b=&a; //b为指针,指向a的地址
    cout<<c<<endl;  //c是a的别名,输出c也就是输出a
    cout<<&c<<endl;  //c的地址=a的地址
    cout<<&a<<endl; //同上一行
    cout<<*&c<<endl;  //先取址,再取内容
    cout<<b<<endl;    //b为指向a的指针,这里输出a的地址
    cout<<*b<<endl;   //该指针指向地址的内容
    
}

在这里插入图片描述

2.cudaMalloc()

在这里插入图片描述

int *dev_a;   //dev_a是一个指针,指向int型变量,存储在主存上,他的内容就是所指变量的地址
size_t size=1024*sizeof(int);
cudaMalloc((void**) &dev_a,size);

为什么是&dev_a而不是dev_a?

  • dev_a是一个指针,存储在主存上;size为一个1024个int的一维数组大小
  • cudaMalloc在显存上申请一个size大小的数组
  • 取dev_a的地址是为了将cudaMalloc在显存上获得的数组首地址赋值给dev_a。
  • 相当于普通的函数调用,是进行值传递还是引用传递。这里相当于调用一个cudaMalloc函数,如果传入dev_a的话,相当于值传递,函数分配好内存后,将地址赋值给dev_a,不会传递到函数外;如果传入&dev_a,相当于引用传递,&能真正改变该地址存储的变量值。

cudaMalloc在执行完成后,向这个地址(&dev_a)中写入了一个地址值(此地址值是GPU显存里的),也就是上边所说,将cudaMalloc在显存上获得的数组首地址赋值给dev_a。

为什么要(void **)?

&dev_a其实就相当于指针的地址,dev_a是一个指针,用一个指针存dev_a的地址,如果用一个变量来表示&dev_a的话,应该是 void ** temp= &dev_a在定义时就是**。也就是说 &dev_a本身的含义就是指针的指针。
根据函数原型,需要是指针的指针(**),所以用void**进行强制类型转化,使得形参实参匹配。

如何理解CUDA中的cudaMalloc()的参数:https://blog.csdn.net/bendanban/article/details/8151335

总结

调用cudaMalloc的作用是分配一个给定大小的空间,返回给传入的地址参数,使得dev_a指向新分配的空间的地址。如果调用cudaMalloc时传入变量名(dev_a)的话,只能进行值传递,而无法进行引用传递,所以要传入变量地址(&dev_a)。由于dev_a是一个指针,指针的地址(&dev_a) 如果用一个变量(temp)来存储的话,也就是该变量是存储(&dev_a)的指针,指向&dev_a,是指针的指针,即void ** temp = &dev_a;

2.cudaMemcpy()

cudaError_t cudaMemcpy (void *dst, const void *src, size_t count, cudaMemcpyKind kind)。
前两个参数都是指针数据类型,含义是地址,因为指针存的就是地址。

double x[N];
double *dev_x;
cudaMalloc( (void**)&dev_x, sizeof(double)*num_v);
cudaMemcpy(dev_x,x,num_v*sizeof(double),cudaMemcpyHostToDevice);

这里前两个参数都要求是指针的形式,其中x由于定义的是double型数组,所以x其实就是数组的起始地址,可以理解为指向数组的指针。

3.cudaFree()

在这里插入图片描述

cudaFree(dev_a);

根据函数原型,第一个参数是指针类型,而dev_a就是指针,所以直接传参而不用进行类型转化。

为什么这里是void* 而cudaMalloc是void**?

因为释放内存的时候,其实不像cudaMalloc,需要函数修改参数(新分配内存的地址),而是只将所指向的内存地址的空间释放就好。

如何理解CUDA中的cudaMalloc()的参数 https://blog.csdn.net/bendanban/article/details/8151335
C++中指针和引用的区别、以及引用和取地址符&的区别 https://blog.csdn.net/jinking01/article/details/82796024

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值