GPU的内存系统GPU内存详解

GPU内存分配命令行 gpu 内存_寄存器

GPU的存储系统包括
register,shared memory,texture memory, local memory, global memory

寄存器 共享纹理 纹理内存 局部内存 全局内存

register

shared memory

local memory

global memory

constant memory

texture memory

主机访问权限




读写

读写

GPU访问权限

同线程读写

同block读写

同线程读写

读写

只读

只写

速度

最快






容量

很小

一般48K


很大



每个thread 都有自己的一份register 和local memory 的空间。

同一个block 中的每个thread 则有共享的一份share memory。
此外,所有的thread(包括不同block 的thread)都共享一份global memory、constant memory、和texture memory。

不同的grid 则有各自的global memory、constant memory 和texture memory。

寄存器

与CPU不同,GPU的每个SM(流多处理器)有成千上万个寄存器,在GPU技术简介中已经提到,SM类似于CPU的核,每个SM拥有多个SP(流处理器),所有的工作都是在SP上处理的,GPU的每个SM可能有8~192个SP,这就意味着,SM可同时运行这些数目的线程。

寄存器是每个线程私有的,并且GPU没有使用寄存器重命名机制,而是致力于为每一个线程都分配真实的寄存器,CUDA上下文切换机制非常高效,几乎是零开销。当然,这些细节对程序员是完全透明的。
和CPU一样,访问寄存器的速度是非常快的,所以应尽量优先使用寄存器。无论是CPU还是GPU,通过寄存器的优化方式都会使程序的执行速度得到很大提高。

for (int i = 0; i < size; ++i)
{
sum += array[i];
}

sum如果存于内存中,则需要做size次读/写内存的操作,而如果把sum设置为局部变量,把最终结果写回内存,编译器会将其放入寄存器中,这样只需1次内存写操作,将大大节约运行时间。

Local memory

Local memory和寄存器类似,也是线程私有的,访问速度比寄存器稍微慢一点。
事实上,是由编译器在寄存器全部使用完的时候自动分配的。在优化程序的时候可以考虑减少block的线程数量以使每个线程有更多的寄存器可使用,这样可减少Local memory的使用,从而加快运行速度。

共享内存

每个线程块都有一个共享内存,该线程块中的线程都可以读取该内存,其他线程块的线程无法访问该共享内存。共享内存帮助同一线程块的线程通信与协作。并且共享内存缓存区实在物理GPU上,而不是其他与GPU相连的设备上,访问效率更高。

常量内存

常量内存通过__constant__来修饰变量,被限制为只读。
1.对常量内存的单次读操作可以广播到该线程的半线程数中,减少15读操作。
2.常量内存的数据将缓存起来,因此对相同地址的连续读操作不会产生额外通信量。