CUDA memory

原文链接

CUDA存储器类型:

每个线程拥有自己的register and loacal memory;

每个线程块拥有一块shared memory;

所有线程都可以访问global memory;

还有,可以被所有线程访问的只读存储器:constant memory and texture memory

1、  寄存器Register

  寄存器是GPU上的高速缓存器,其基本单元是寄存器文件,每个寄存器文件大小为32bit.

  Kernel中的局部(简单类型)变量第一选择是被分配到Register中。

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

2、  局部存储器 local memory

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

  特点:每个线程私有;没有缓存,慢。

  注:在声明局部变量时,尽量使变量可以分配到register。如:

  unsigned int mt[3];

  改为: unsigned int mt0, mt1, mt2;

3、  共享存储器 shared memory

  可以被同一block中的所有线程读写

  特点:block中的线程共有;访问共享存储器几乎与register一样快.

 1 //u(i)= u(i)^2 + u(i-1)
 2 //Static
 3 __global__ example(float* u) {
 4     int i=threadIdx.x;
 5     __shared__ int tmp[4];
 6      tmp[i]=u[i];
 7      u[i]=tmp[i]*tmp[i]+tmp[3-i];
 8 }
 9
10 int main() {
11     float hostU[4] = {1, 2, 3, 4};
12      float* devU;
13     size_t size = sizeof(float)*4;
14     cudaMalloc(&devU, size);
15     cudaMemcpy(devU, hostU, size,
16     cudaMemcpyHostToDevice);
17      example<<<1,4>>>(devU, devV);
18     cudaMemcpy(hostU, devU, size,
19     cudaMemcpyDeviceToHost);
20     cudaFree(devU);
21     return 0;
22 }
23
24 //Dynamic
25 extern __shared__ int tmp[];
26
27 __global__ example(float* u) {
28     int i=threadIdx.x;
29      tmp[i]=u[i];
30      u[i]=tmp[i]*tmp[i]+tmp[3-i];
31 }
32
33 int main() {
34     float hostU[4] = {1, 2, 3, 4};
35     float* devU;
36     size_t size = sizeof(float)*4;
37     cudaMalloc(&devU, size);
38     cudaMemcpy(devU, hostU, size, cudaMemcpyHostToDevice);
39      example<<<1,4,size>>>(devU, devV);
40     cudaMemcpy(hostU, devU, size, cudaMemcpyDeviceToHost);
41     cudaFree(devU);
42     return 0;
43 }

 4、  全局存储器 global memory

  特点:所有线程都可以访问;没有缓存

//Dynamic
__global__ add4f(float* u, float* v) {
int i=threadIdx.x;
 u[i]+=v[i];
}
int main() {
    float hostU[4] = {1, 2, 3, 4};
    float hostV[4] = {1, 2, 3, 4};
    float* devU, devV;
    size_t size = sizeof(float)*4;
    cudaMalloc(&devU, size);
    cudaMalloc(&devV, size);
    cudaMemcpy(devU, hostU, size,
    cudaMemcpyHostToDevice);
    cudaMemcpy(devV, hostV, size,
    cudaMemcpyHostToDevice);
    add4f<<<1,4>>>(devU, devV);
    cudaMemcpy(hostU, devU, size,
    cudaMemcpyDeviceToHost);
    cudaFree(devV);
    cudaFree(devU);
    return 0;
}

//static
__device__ float devU[4];
__device__ float devV[4];

__global__ addUV() {
int i=threadIdx.x;
 devU[i]+=devV[i];
}

int main() {
    float hostU[4] = {1, 2, 3, 4};
    float hostV[4] = {1, 2, 3, 4};
    size_t size = sizeof(float)*4;
    cudaMemcpyToSymbol(devU, hostU, size, 0, cudaMemcpyHostToDevice);
    cudaMemcpyToSymbol(devV, hostV, size, 0, cudaMemcpyHostToDevice);
     addUV<<<1,4>>>();
    cudaMemcpyFromSymbol(hostU, devU, size, 0, cudaMemcpyDeviceToHost);
    return 0;
}

   5、  常数存储器constant memory

  用于存储访问频繁的只读参数

  特点:只读;有缓存;空间小(64KB)

   注:定义常数存储器时,需要将其定义在所有函数之外,作用于整个文件

1 __constant__ int devVar;
2 cudaMemcpyToSymbol(devVar, hostVar, sizeof(int), 0, cudaMemcpyHostToDevice)
3 cudaMemcpyFromSymbol(hostVar, devVar, sizeof(int), 0, cudaMemcpyDeviceToHost)

 6、  纹理存储器 texture memory

是一种只读存储器,其中的数据以一维、二维或者三维数组的形式存储在显存中。在通用计算中,其适合实现图像处理和查找,对大量数据的随机访问和非对齐访问也有良好的加速效果。

特点:具有纹理缓存,只读。

时间: 2024-12-09 08:50:52

CUDA memory的相关文章

CUDA ---- Memory Model

Memory kernel性能高低是不能单纯的从warp的执行上来解释的.比如之前博文涉及到的,将block的维度设置为warp大小的一半会导致load efficiency降低,这个问题无法用warp的调度或者并行性来解释.根本原因是获取global memory的方式很差劲. 众所周知,memory的操作在讲求效率的语言中占有极重的地位.low-latency和high-bandwidth是高性能的理想情况.但是购买拥有大容量,高性能的memory是不现实的,或者不经济的.因此,我们就要尽量

并行程序设计---cuda memory

CUDA存储器模型: GPU片内:register,shared memory: host 内存: host memory, pinned memory. 板载显存:local memory,constant memory, texture memory, texture memory,global memory; register: 訪问延迟极低: 基本单元:register file (32bit/each) 计算能力1.0/1.1版本号硬件:8192/SM. 计算能力1.2/1.3版本号硬

【Cuda并行编程之二】Cuda Memory Hierarchy_Cuda内存层次结构

要想编写高效的程序,那么一定要对内存结构有比较深刻的认识,就像C/C++里面的堆内存,栈内存,全局存储区,静态存储区,常量区等.Cuda是并行计算框架,而GPU的内存有限,那么如果想编写高效的Cuda程序,首先要对其内存结构有一个简单的认识. 首先我们先上一张图,然后通过解释一些名词和代码来进行解释. 各种存储器比较: 存储器  位置 拥有缓存 访问权限 变量生存周期 register GPU片内 N/A device可读/写 与thread相同 local memory 板载显存 无 devi

CUDA系列学习(二)CUDA memory &amp; variables

本文来介绍CUDA的memory和变量存放,分为以下章节: (一).CPU Memory 结构 (二).GPU Memory结构 (三).CUDA Context (四).kernel设计 (五).变量 & Memory 5.1 global arrays 5.2 global variables 5.3 Constant variables 5.4 Register 5.5 Local Array 5.6 Shared Memory 5.7 Texture Memory 5.8 总结 (一).

CUDA ---- Memory Access

Memory Access Patterns 大部分device一开始从global Memory获取数据,而且,大部分GPU应用表现会被带宽限制.因此最大化应用对global Memory带宽的使用时获取高性能的第一步.也就是说,global Memory的使用就没调节好,其它的优化方案也获取不到什么大效果. Aligned and Coalesced Access 如下图所示,global Memory的load/store要经由cache,所有的数据会初始化在DRAM,也就是物理的devi

CUDA系列学习(三)GPU设计与结构QA &amp; coding练习

啥?你把CUDA系列学习(一),(二)都看完了还不知道為什麼要用GPU提速? 是啊..经微博上的反馈我默默感觉到提出这样问题的小伙伴不在少数,但是更多小伙伴应该是看了(一)就感觉离自己太远所以赶紧撤粉跑掉了...都怪我没有写CUDA系列学习(零)...那么,这一章就补上这一块,通过一堆Q&A进行讲解,并辅助coding练习,希望大家感觉贴近CUDA是这么容易~~ 请注意各个Q&A之间有顺序关系,轻依次阅读~ 否则不容易懂喔~ Q:现在硬件层面通常通过什么样的方法加速?A: - More p

CUDA(六). 从并行排序方法理解并行化思维——冒泡、归并、双调排序的GPU实现

在第五讲中我们学习了GPU三个重要的基础并行算法: Reduce, Scan 和 Histogram,分析了 其作用与串并行实现方法. 在第六讲中,本文以冒泡排序 Bubble Sort.归并排序 Merge Sort 和排序网络中的双调排序 Bitonic Sort 为例, 讲解如何从数据结构课上学的串行并行排序方法转换到并行排序,并附GPU实现代码. 在并行方法中,我们将考虑到并行方法需要注意的特点进行设计,希望大家在读完本文后对GPU上并行算法的设计有一些粗浅的认识.需注意的特点如下: 1

2.2CUDA-Memory(存储)

在CUDA基本概念介绍有简单介绍CUDA memory.这里详细介绍: 每一个线程拥有自己的私有存储器,每一个线程块拥有一块共享存储器(Shared memory):最后,grid中所有的线程都可以访问同一块全局存储器(global memory).除此之外,还有两种可以被所有线程访问的只读存储器:常数存储器(constant memory)和纹理存储器(Texture memory),它们分别为不同的应用进行了优化.全局存储器.常数存储器和纹理存储器中的值在一个内核函数执行完成后将被继续保持,

优达学城-并行编程-Unit2 通信模块、同步机制、原子操作

(一). Parallel communication Patterns 在上一章CUDA系列学习(二)CUDA memory & variables中我们介绍了memory和variable的不同类型,本章中根据不同的memory映射方式,我们将task分为以下几种类型:Map, Gather, Scatter, Stencil, transpose. 1.1 Map, Gather, Scatter Map: one input - one output Gather: several in