一、显卡的内存
显卡的内存从本质讲和普通的内存没有什么区别,都是易失性的存储器。可以简单的把内存理解为计算单元的大容量的临时存储器。但中国有句古话“橘生淮南则为橘,生淮北则为枳”。在不同的环境下,同样目的设计的硬件,可能具体的要求有所不同,那么就会存在不同的特点。
再举一个例子,同样是刀,骑马战阵则是是青龙偃月刀,近身肉搏则是短刀,而唐朝为了与骑兵对抗则有陌刀。其实显存和普通内存的区别也是这样。至于具体的不同主要体现在:
1、显存为实现并行计算和图形渲染,广泛采用更高带宽的GDDR6等内存
2、相对普通内存来说其延迟性较高,通常相比普通内存容量也较小
3、相对普通内存功耗较大且为显卡独占
因为这种不同,是应用场景的具体的需求产生的,所以下面对CUDA模型中的内存管理进行分析说明。
三、CUDA中内存的模型
CUDA内存模型重点指的是设备端的内存模型,对于HOST端的就不再说明了。在设备端,CUDA的内存主要分成以下几部分:
1、全局内存(设备内存)
全局内存类似于普通编程中的内存,所有线程和主机端都可以访问,而且应用过程需要开发者自行管理相关内存的释放和分配。其又可以根据特点划分出常量内存和本地内存(线程私有),常量内存一般存在于缓存中,访问速度较快且大小固定。本地内存可以理解为线程的局部存储内存,访问速度较慢。
2、缓存
缓存的目的都是用来提高访问速度,都是计算的局部性原理的体现。不同的在于,GPU是空间局部性的体现而CPU是时间局部性的体现。大家都知道,CPU的缓存分几级的且一级比一级大,最大的已经是兆级的了。而在GPU中,L2和L1缓存都相当小,只有几十个字节。L1缓存在不同的架构体系上略有不同,在某些场景下它和共享内存是一体的。
3、共享内存
共享内存是GPU芯片上的片上内存,是SM内存的存储资源,其仅对同一Block内的线程所见,生命周期与线程块一致,共享内存的大小固定,通常为64K或128K。内存通常需要手动管理
4、纹理内存和表面内存
纹理内存和表面内存其实也是全局内存的一部分,但由于它们的访问和控制方式不同,所以专门分出来分析。纹理内存由于是只读的,所以其可以通过专用的纹理缓存进行加速访问,提高访问速度,支持自动插值和数据转换;表面内存通过直接访问接口(非缓存)提供读写操作,支持随机操作,其性能受显存带宽的影响。
它们的共同特征其实是复用硬件并提供API接口,实现高效的访问模式。一般来说,建议优先使用纹理内存然后选择表面内存,最后在使用全局内存。
需要说明的是,GPU的架构体系是在演进的,所以其内存架构也在不断的发展,而CUDA针对具体的架构可能会有不同的改变甚至根本性的变化,这就需要开发者来自行根据当前的实际开发环境进行动态调整。
三、CUDA内存的优化及应用
1、使用固定内存
使用固定内存可以优化主机与设备间的数据传输。操作系统会保证此块内存不会被交换到磁盘中去。结果就是可以通过DMA的方式进行直接的数据拷贝,降低开销,提高传输效率。在异步操作时,更能体现其优势。
2、使用统一内存
统一内存是用来保证可移植性的一个重要手段,它可以简化CPU和GPU的内存管理,其提供了一个统一的内存空间视图,供主机端和设备端共同访问。统一内存优化的方式主要有:对每页的Wrap进行优化;使用数据预取。
3、全局内存优化
合并访问会减少总线带宽的浪费,而利用缓存则可以提高访问的效率;同样使用L2缓存同样可以提高访问速度。
4、使用和优化共享内存
在共享内存中避免Bank冲突并进行数据填充(保证对齐,防止冲突),由于共享内存是可以明确管理的,所以通过实际的需求来提高效率。
5、合理使用纹理内存
在只读的非对齐数据访问以及需要自动插值的情况下,优秀使用纹理内存。
CUDA中,重要的应用场景有矩阵的算法、图像的处理等。在这些情况下,恰恰可以使用纹理内存和共享内存的优化来进行处理。同样,为了提高交互效率,使用固定内存可以更好的提高处理速度,如此等等。所以明白CUDA内存模型的特点,再去相应的进行应用,有事半功倍的效果。
四、总结
这里并没有分析寄存器,虽然某种角度上可以将其划分成缓存。可是仍然觉得寄存器的原理和目的一般开发者应该都会明白,所以就不再展开了。CUDA的内存整体的形象就有一个明显的轮廓,以后会不断的深入进去,不断分析说明,从外及内,最终掌握相关的技术。

2158

被折叠的 条评论
为什么被折叠?



