首页 > 解决方案 > 在 cuda 线程之间共享大量常量数据

问题描述

我有一个被多次调用的内核。在每次调用中,大约 240 KB 的常量数据将由线程共享和处理。线程像地图函数一样独立工作。线程的停顿时间相当长。其背后的原因可能是内存读取的银行冲突。我该如何处理?(我有 GTX 1080 ti)

opencl的“const global”可以处理吗?(因为 cuda 中的常量内存限制为 64 kb)

标签: c++cudaopencl

解决方案


在 CUDA 中,我相信最好的建议是使用所谓的“只读”缓存。__constant__与内存/常量缓存系统相比,这至少有两个可能的好处:

  1. 它不限于像__constant__内存那样的 64kB。
  2. 它不像常量缓存那样期望或要求“统一访问”来提供完整的访问带宽/最佳性能。统一访问是指 warp 中的所有线程都在访问相同的位置或相同的常量内存值(每个读取周期/指令)的想法。

只读缓存记录在CUDA 编程指南中。使用它的最简单方法可能是使用(假设您没有在指针之间出现别名)装饰传递给 CUDA 内核的指针,并使用. 这将允许编译器生成适当的 LDG 指令以访问常量数据,并通过只读缓存机制将其拉出。__restrict__const ... __restrict__

这种只读缓存机制仅在 cc 3.5 或更高版本的 GPU 上受支持,但它涵盖了 Kepler 一代中的一些 GPU 以及 Maxwell、Pascal(包括您的 GTX 1080 ti)、Volta 和 Turing 一代中的所有 GPU。

如果您的 GPU 小于 cc3.5,那么对于类似好处(大于__const__,不需要统一访问)的最佳建议可能是使用纹理内存。这也记录在编程指南的其他地方,有各种 CUDA 示例代码演示了纹理内存的使用,还有很多关于 SOcuda标签的问题也涵盖了它。


推荐阅读