CUDA内存整理

函数类型

__device__  标记的函数从一个在器件中执行的函数呼叫,在器件中执行 
__global__  表示该函数从一个在主机中执行的函数呼叫,在器件中执行
__host__     表示在主机中呼叫,在主机中执行的函数

 

线程

grid里面包含block,block里面包含thread

grid里面所有的block都是同样大小的,每个block最多可以有1024个thread。

blockDim表示一个block里面thread的数量。

block里面每个thread都有一个独一无二的编号,threadIdx

 

记忆体

在CUDA里,host和devices有不同的记忆体空间。
     首先呢,CUDA的memory有很多种类

     1. Global memory

     2. Constant memory

     这两种memory可以由CPU上运行的函数呼叫读写。

     Global memory 这个,学过一点点CUDA的都知道,一般说device memory  指的就是它,


     Constant memory 有低延迟,高带宽,但是device只能读它不能写它,并且所有线程可以同时访问同一地址。

     3. Register

     4. Shared memory

     这两种memory是片上记忆体(on-chip),换句话说,读写速度要比前两种memory多很多,至于到底多多少,有空测试哈,而且可以以高度并行的模式读写。

     Registers是被分配给单独的线程的,每个线程只能链接自己的register。

     Shared memory 是被分配给block的。block里所有的线程都可以访问属于这个block的Shared Memory,共享记忆体是一个十分有效的工具,可以共享他们的输入信息和他们计算出来的中间结果。

 

各个记忆体的编程模型:

Global memory  VS Register


     1. Global memory: "The von Neumann Model": 这个记忆体在cuda编程模型中可以映射到冯诺依曼结构中的记忆体。

                                    global memory 是在处理器芯片之外独立的记忆体,且应用的是动态随机存取存储器(Dynamic Random Access Memory,DRAM)技术。

                                    所以会有很长的链接延迟,和相对来说较低的带宽。

    2. Registers: 它有点类似于The von Neumann Model 中的“register file”,它在处理器芯片里面,所以链接的延迟非常的低,以及非常高的带宽。一般器件的Register的综合接入带宽是global memory的两个数量级大。此外,无论何时,链接Register的带宽不占用个global的带宽。另外比起链接global memory, 所需要的执行的指令也要少很多。一般的处理器对于算数指令都有内嵌的寄存器运算数,例如,浮点加法指令:

    fadd r1,r2,r3

    其中 r2,r3是寄存器的编号,用来提取要做加法的数,最后存到r1中去 。

    如果要做加法的数字存在global memory里,首先要从global memory中把数据提取到ALU中,然后在进行浮点运算。

    load r2,r4,offset

    fadd r1,r2,r3

    load命令可以把数据从r4中提取出来,存入r2 再进行加法。

    另外还有一个是建议把运算数值存在register的原因,在现代计算机中,从一个register里调用数据一般比从global memory中调用数据所消耗的能量要低一个数量级。

 

   补充说明:执行单位和线程之间的关系,现在我们介绍一下冯诺依曼结构,现代计算机中的线程是一个虚拟化的冯诺依曼处理器,一个线程包含了程式的一部分代码,正要执行的那部分,还有涉及到的数据和数据结构。    在基于冯诺依曼模型的计算机中,代码是存储在记忆体中的,PC不停的访问程式正要进行的那部分,IR则用来存储正要执行的指令。而寄存器和记忆体贼存储数据和数据结构。    现代处理器允许


Shared memory VS Register

    他们都是 on-chip 记忆体,但是当处理期要从Shared memory中调用数据时,需要有从记忆体载入数据这个操作,如同从global memory中调用数据一样。但是因为它是片上记忆体,所以无论延迟还是带宽,都比global memory有明显的优势。但因为有load这个步骤,所以无论带宽还是延时比较register都有明显的劣势。

    Shared memory存储的变量是被一个block里所有线程共享的。但是register里的变量是线程私有的。Shared memory 能很好地支持thread之间资料共享。

你可能感兴趣的:(CUDA内存整理)