【发布时间】:2017-08-11 03:10:16
【问题描述】:
我很难理解对 CUDA 常量内存的限制。
-
为什么我们不能在运行时分配
__constant__内存?为什么需要在近全局范围的固定大小变量中进行编译? -
什么时候实际加载或卸载常量内存?我知道
cudaMemcpytoSymbol用于加载特定的数组,但是每个内核是否使用自己的常量内存分配?相关的是,绑定和解除绑定是否有类似于绑定纹理的旧成本(也就是使用纹理会为每次内核调用增加成本)的成本? -
常量内存驻留在芯片的什么位置?
我主要对与 Pascal 和 Volta 相关的答案感兴趣。
【问题讨论】:
-
不,每个内核都不会获得或使用自己分配的
__constant__内存。没有绑定/解除绑定成本。__constant__内存是一个逻辑空间。物理支持由 DRAM 的特定区域和常量缓存组成。常量缓存是每个 SM 资源。 DRAM 是一种片外资源。逻辑空间的最大大小为 64KB。这并不意味着每个 SM 缓存是 64KB。常量缓存的实际大小没有很好地指定,并且可能会从一个 GPU 架构更改为另一个,但每个 SM 大约为 8KB。 -
@RobertCrovella 那么,什么时候卸载常量缓存?是否为每次调用加载/卸载?除其他外,我担心代码中不相关部分中存在一些巨大的
__constant__对象,可能会超过 const 缓存大小。 -
@RobertCrovella 另外,我理解它是一个逻辑空间,但我不确定到该空间的物理映射中还有什么(试图围绕常量缓存的一些限制)
-
常量缓存,就像我熟悉的大多数其他缓存一样,在您访问 (
__constant__) 内存时被加载。大多数缓存不是这样工作的吗?我熟悉的缓存没有明确的“加载”或“卸载”。从程序员的角度来看,缓存在基本层面上是一个透明的实体。如果您问常量缓存是否有任何全局失效,我很确定信息没有在任何地方指定。 “未指定”的后果之一是它可能随时更改,因此今天给出的“答案”明天可能是错误的。 -
@RobertCrovella 好吧,它通过
cudaMemcpytoSymbol显式加载,所以它不像传统的缓存。当然不像 x86 缓存是神奇地“缓存”的东西。感觉更像共享内存,但有更多限制。