Mik*_*ail 3 cuda gpu-constant-memory
我无法绕过对CUDA恒定内存的限制.
__constant__
在运行时分配内存?为什么我需要在具有接近全局范围的固定大小变量中进行编译?什么是常量内存实际加载或卸载?我明白cudaMemcpytoSymbol
用于加载特定的数组,但每个内核是否都使用自己的常量内存分配?相关,是否有绑定和解除绑定的成本类似于绑定纹理的旧成本(也就是说,使用纹理为每个内核调用添加了成本)?
常量内存驻留在芯片上的哪个位置?
我主要对与Pascal和Volta有关的答案感兴趣.
以相反的顺序回答这六个问题可能是最简单的:
常量内存驻留在芯片上的哪个位置?
它没有.常量存储器存储在片外静态保留的物理存储器中,并通过per-SM缓存访问.当编译器可以识别变量存储在逻辑常量存储空间中时,它将发出特定的PTX指令,允许通过常量高速缓存访问该静态存储器.另请注意,存在特定的保留常量存储库,用于在所有当前支持的体系结构上存储内核参数.
是否有成本绑定和解除绑定类似于绑定纹理的旧成本(也就是说,使用纹理为每个内核调用添加了成本)?
不.但是也没有"绑定"或"解除绑定",因为预订是静态执行的.唯一的运行时成本是设备内存传输的主机以及将符号作为上下文建立的一部分加载到上下文中的成本.
我明白
cudaMemcpytoSymbol
用于加载特定的数组,但每个内核是否都使用自己的常量内存分配?
没有.整个GPU只有一个"分配"(尽管如上所述,内核参数有特定的常量内存库,因此在某种意义上你可以说每个内核组件都有一个常量内存).
什么是常量内存实际加载或卸载?
这取决于你所说的"装载"和"卸载".加载实际上是一个两阶段过程 - 首先检索符号并将其加载到上下文中(如果使用运行时API,这是自动完成的),其次是任何用户运行时操作来改变常量内存的内容 cudaMemcpytoSymbol
.
为什么我需要在具有接近全局范围的固定大小变量中进行编译?
如前所述,常量存储器基本上是PTX存储器层次结构中的逻辑地址空间,其由GPU DRAM映射的有限大小保留区域反映,并且需要编译器发出特定指令以通过专用片上高速缓存或缓存.鉴于其静态的,编译器分析驱动的性质,它在语言中的实现也将主要是静态的.
为什么我们不能
__constant__
在运行时分配内存?
主要是因为NVIDIA选择不公开它.但考虑到上面列出的所有限制因素,我认为这不是一个令人难以置信的糟糕选择.其中一些可能是历史性的,因为从一开始,恒定存储器就是CUDA设计的一部分.CUDA设计中的几乎所有原始特性和功能都映射到硬件特性,这些特性是硬件的第一个目的,即GPU设计支持的图形API.因此,您所询问的一些内容很可能与OpenGL或Direct 3D的历史功能或限制有关,但我对其中任何一个都不太熟悉.