【发布时间】:2018-01-07 15:14:49
【问题描述】:
我正在尝试学习 OpenCL,但我很难决定使用哪些地址空间,因为我只找到了声明这些地址空间是什么的组合资源,但没有说明它们存在的原因或何时使用它们。资源至少太分散了,所以带着这个问题,我希望把所有这些信息都收集起来:所有的地址空间是什么,它们为什么存在,什么时候使用哪个地址空间,关于内存的优缺点是什么和性能。
据我了解(这可能过于简化),GPU 有两种物理类型的内存:全局内存,与实际的处理器相距甚远,速度慢但相当大,可供所有工作人员使用和本地内存,接近实际的处理器,速度如此之快,但很小,其他工作人员无法访问。
直观地说,local 限定符确保将变量放置在本地内存中,global 限定符确保将变量放置在全局内存中,尽管我不确定这正是发生的情况。这留下了 private 和 constant 限定符。这些的目的是什么?
还有一些隐含的限定符。例如,the specifications 提到了通用地址空间,我认为它用于没有限定符的参数。这到底是做什么的?然后还有局部函数变量。这些地址空间是什么?
这是一个使用我的直觉但不知道我实际在做什么的例子:
示例:
假设我将一个类型为 long 且长度为 10000 的数组传递给一个仅用于读取的内核,然后我将其声明为 global const,因为它必须可供所有工作人员使用并且它不会改变。为什么我不使用constant 限定符?当通过 CPU 为这个数组设置缓冲区时,我实际上也可以将数组设为只读,在我看来,这与声明它 const 相同。再说一次,我何时以及为什么要声明 constant 或 global const?
在执行内存密集型任务时,将数组复制到内核内部的本地数组会更好吗?我的猜测是本地内存太小了,但是如果数组只有 10 的长度呢?数组什么时候会太大/太小?更笼统地说:什么时候值得将数据从全局内存复制到本地内存?
假设我还想传递这个数组的长度,那么我会将const int length 添加到我的内核的参数中,但我不确定为什么我会省略global 限定符,除非因为我见过其他人做。毕竟,length 必须可供所有工作人员访问。如果我是对的,那么length 将有一个通用地址空间,但同样,我真的不知道这意味着什么。
我希望有经验的人能解决这个问题。这不仅对我很有帮助,我也希望对其他想要获得有关 GPU 内存管理的实用知识的爱好者也有帮助。
【问题讨论】:
-
常量:从所有内核访问同一个单元的速度很快。全局:对合并的邻居地址的访问速度很快。 local:没有冲突的访问速度很快。私人:它的快。例外:单个全局/本地可以广播到所有核心。 global 服务于 gpu 的所有内核,local 服务于一个计算单元的所有内核,constant 服务于 gpu 的所有内核,private 服务于单个内核。核心,我的意思是工作项。
标签: memory opencl memory-address