常量内存
常量内存是用于存储代码执行期间不会发生改变的数据,其不同于全局内存,使用常量内存替换全局内存能有效的减少内存带宽。常量内存资源一般只有64k,所以是比较稀缺的资源。
其主要原因:
- 对常量内存的单次读操作可以广播到相邻的线程,相当于一次读取,16个线程都能获取到该数据。
- 发生读操作后,常量内存将会被缓存起来,相同的读取操作将不会再产生额外的内存通信量。
在CUDA架构中,线程束指的是一个32线程的集合,在这个集合中的线程,将会LockStep(步调一致)的形式执行。而nvidia硬件会把单次的读操作广播到每个半线程束(half-warp),也就是16个线程中,也就是,如果在这个half-warp中线程都需要读取同一个常量内存数据,那么只需要读取一次,然后通过广播的形式传递到剩余的线程中。所以这种方式,要比全局内存的读取节省1/16的内存流量。
而这块内存被读取后,会被缓存到GPU上,后面在读取该数据的时候只需要从缓存上读取即可,同样也不再需要额外的内存流量。这样会极大程度上提升性能。
但是如果half-warp中每个线程读取的常量内存地址是不同的,也就意味着需要各自取读取,这样性能反而不如全局内存。
常量内存变量修饰符是__constant__
,和C++中const是一样的,被__constant__
修饰的变量将不能改变。
其次常量内存拷贝需要使用cudaMemcpyToSymbol
,cudaMemcpy
是拷贝数据至全局内存。
最简单的例子,如果计算中,每个位置上的数据都需要加减一个数据时,就可以使用常量内存。
纹理内存
纹理内存是CUDA中另一种只读内存,广泛应用于OpenGL和DirectX等工具的渲染操作。
纹理内存是专门为那些内存访问中存在大量空间局部性的图形应用程序设计的,同样需要使用cudaBindTexture
将变量绑定到纹理内存区域。
我个人主要从事的是图像处理方面的工作,暂时不多做介绍了,后续有需要,再来填坑。