【CUDA编程】CUDA内存模型 test ok

1. 内存结构

在CUDA中可编程内存的类型有:

  • 寄存器(Registers)
  • 本地内存(Local Memory)
  • 共享内存(Shared Memory)
  • 常量内存(Constant Memory)
  • 纹理内存(Texture Memory)
  • 全局内存(Global Memory)

CUDA中的内存模型分为以下几个层次:

  • thread:每个线程都用自己的registers(寄存器)和local memory(局部内存)
  • block:每个线程块(block)内都有自己的shared memory(共享内存),所有线程块内的所有线程共享这段内存资源
  • grid:每个grid都有自己的global memory(全局内存),constant memory(常量内存)和texture memory(纹理内存),不同线程块的线程都可使用。其中常量内存和纹理内存为只读内存空间

线程访问这几类存储器的速度是:register > shared memory >Constant Memory > Texture Memory > Local Memory and Global Memory。下面这幅图表示这些内存在计算机架构中的所在层次。

在这里插入图片描述

2. GPU device内存

2.1 寄存器(Registers)

内核函数中声明且没有其他修饰符修饰的变量通常是存放在GPU的寄存器中,比如下面代码中的线程索引变量i。寄存器通常用于存放内核函数中需要频繁访问的线程私有变量,这些变量与内核函数的生命周期相同,内核函数执行完毕后,就不能再对它们进行访问了。

特点:每个线程私有,速度快

__global__ void VectorAddGPU(const float *const a, const float *const b,
                             float *const c, const int n) {
  int i = blockDim.x * blockIdx.x + threadIdx.x;  //变量i 在寄存器中
  if (i < n) {
    c[i] = a[i] + b[i]; 
  }
}

    寄存器是GPU中访问速度最快的内存空间,但是一个SM中寄存器的数量比较有限,一旦内核函数使用了超过硬件限制的寄存器数量,则会使用本地内存来代替多占用的寄存器,这种寄存器溢出的情况会带来性能上的不利影响,实际编程过程中我们应该避免这种情况。

    使用nvcc的编译选项maxrregcount可以控制内核函数使用的寄存器的最大数量:

    -maxrregcount=32
    

      2.2 本地内存(Local Memory)

      当register耗尽时,数据将被存储到local memory。如果每个线程中使用了过多的寄存器,或声明了大型结构体或数组,或编译器无法确定数组大小,线程的私有数据就会被分配到local memory中。,可能存放到本地内存中的变量有:

      • 编译时使用未知索引引用的本地数组
      • 可能会占用大量寄存器空间的较大本地结构体或者数组
      • 任何不满足内核函数寄存器限定条件的变量

      特点:每个线程私有;没有缓存,慢。
       
      溢出到本地内存中的变量 本质上与全局内存在同一块区域 。

      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包

      打赏作者

      小硕算法工程师

      你的鼓励将是我创作的最大动力哈

      ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
      扫码支付:¥1
      获取中
      扫码支付

      您的余额不足,请更换扫码支付或充值

      打赏作者

      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

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

      余额充值