9

我想了解当我创建具有只读属性的缓冲区并将其与__constant内核中的地址空间限定符一起使用或与const __global地址空间限定符一起使用时有什么区别。

我已经发现这些并不是我问题的真正答案,但它们包含一些有用的信息:

如果我理解得很好,GPU 内存中的分配发生在 clCreateBuffer 函数调用中。所以我不明白的是编译器如何决定缓冲区是在常量内存(有 64 KB 的限制)还是在全局内存中。(我知道在大多数情况下,常量内存是全局内存空间的一部分。)如果它取决于地址限定符,这意味着可以使用const __global.

__constant和之间的性能有什么区别const __global吗?__global 内存可能会被缓存,因此它们都是只读的并且(可能)被缓存。(来源:3.3 内存模型/全局内存部分和图 3.3; http://www.khronos.org/registry/cl/specs/opencl-1.x-latest.pdf#page=24

4

4 回答 4

3

根据我的经验,两者在概念上没有区别,它们都暗示指向的数据是只读的。只有根据供应商使用的实现,差异才会变得明显。

例如,在 nvidia GPU 上,标有 __constant 的内存被缓存(我相信所有当前设备的缓存大小为每个多处理器 8KB)。需要注意的一点是,如果不同的工作项访问不同的地址,则对该缓存的访问是序列化的,因此我发现它对于传递工作组中的常量参数结构最有用。如果您查看 CUDA 编程指南中关于常量内存的部分,您会更好地了解它是如何工作的。我相信,标记为 const __global 的内存不会被缓存,它只是告诉编译器在您尝试更改指向的值时抛出错误。

我不确定 AMD 是否在他们的硬件上做类似的缓存

希望有帮助

于 2013-08-01T13:07:39.940 回答
2

对于面向 FPGA 上的 OpenCL 的英特尔(以前的 Altera)SDK,常量内存被加载到由所有工作组共享的片上常量缓存中。默认情况下,此缓存的大小为 16 KB,但可以通过在命令中添加-const-cache-bytes=<N>(以<N>字节为单位的常量缓存大小)标志进行更改aoc。他们的最佳实践指南第 138 页还提到了以下内容:

与具有额外硬件来容忍长内存延迟的全局内存访问不同,常量缓存会因缓存未命中而遭受巨大的性能损失。如果 __constant 您的 OpenCL 内核代码中的参数无法放入缓存中,您可能会使用 __global const 参数来获得更好的性能。

于 2018-06-19T15:15:55.123 回答
0

AMD 的 OpenCL 实现请看这里的解释: https ://github.com/RadeonOpenCompute/ROCm/issues/203

基本上,常量具有隐式限制的效果。因此,常量 int *p主要等价于const global int * restrict p

于 2017-09-13T08:56:36.217 回答
-1

constant类似于Dimmutable_ 这意味着在整个内核执行期间(所有工作项)该值不会改变。 另一方面,只表示指向的内存不会通过这个指针改变,但仍然可以通过别名的非指针改变。const constconst

constant暗示const(如果没有人可以更改数据,那么您也不能)。

constant对编译器来说是一个巨大的优化机会。它可以发出代码为每个工作项取消引用指针一次并将值保存在寄存器中(GPU 有很多寄存器!),甚至可以在子组中的不同工作项之间共享取消引用的值。

至于编译器如何确定缓冲区在常量内存中,很简单:如果你写constant在内核中,它就是常量地址空间。这意味着该决定不早于clSetKernelArg当时做出。

于 2021-08-23T17:18:45.070 回答