c++ - 在 cuda 线程之间共享大量常量数据

标签 c++ cuda opencl

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

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

最佳答案

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

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

只读缓存记录在 the CUDA programming guide 中.可能最简单的使用方法是 decorate your pointers使用 __restrict__ 传递给 CUDA 内核(假设您是 not aliasing between pointers )并使用 const ... __restrict__ 装饰指向大常量数据的指针。这将允许编译器生成适当的 LDG 指令以访问常量数据,通过只读缓存机制拉取它。

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

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

关于c++ - 在 cuda 线程之间共享大量常量数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53149193/

相关文章:

c++ - 填充 CUDA 内核中的数组或列表,但不是在每个线程中

linux - libfreenect2 示例 Protonect 仅显示原始饲料?

c++ - C++中异常类的继承

c++ - 唯一指针的 Memset

c++ - 在构造函数 C++ 中用零初始化二维数组

c++ - CUDA 矩阵加法段错误

c - 在 CUDA C 中确定计算机在运行时是否有 GPU

memory - AMD 7970 报告不正确的 DEVICE_GLOBAL_MEM_SIZE

python - 旗鱼 : how to run on computer without gpu

c++ - 未使用重载运算符 []