#寄存器


与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.常量内存的数据将缓存起来,因此对相同地址的连续读操作不会产生额外通信量。