Saf*_*ron 4 memory opencl memory-address
我正在尝试学习OpenCL,但是我很难确定要使用的地址空间,因为我只能找到汇编资源来声明这些地址空间是什么,而不是它们为什么存在或何时使用它们。资源至少太分散了,因此我希望将所有这些信息汇总在一起:所有的地址空间是什么,它们为什么存在,何时使用哪个地址空间,以及在内存和性能方面的优缺点是什么?
据我了解(可能过于简化),GPU具有两种物理类型的内存:全局内存,远离实际处理器,因此速度较慢,但很大,可供所有工作人员使用;而本地内存则接近实际处理器,但速度很快,但体积很小,其他工作人员无法访问。
直观上,local限定符确保将变量放置在本地内存上,而global限定符确保将变量放置在全局内存上,尽管我不确定这是否会发生。剩下private和constant限定词。这些的目的是什么?
也有一些隐式的限定词。例如,我认为规范提到了通用地址空间,该地址空间用于没有限定符的参数。这到底是做什么的?然后还有局部函数变量。这些地址的空间是什么?
这是一个使用我的直觉的示例,但是不知道我实际上在做什么:
示例:
假设我将类型long和长度为10000 的数组传递给内核,该内核将仅用于读取,然后我将声明它,global const因为它必须对所有工作人员都可用并且不会更改。我为什么不使用constant限定词?当通过CPU为该数组设置缓冲区时,实际上我也可以将数组设为只读,在我看来这与声明它相同const。如此反复,什么时候,为什么我会申报的东西constant还是global const?
在执行内存密集型任务时,将阵列复制到内核内部的本地阵列会更好吗?我的猜测是本地内存太小,但是如果数组的长度只有10怎么办?阵列何时会过大/过小?更笼统:什么时候值得将数据从全局内存复制到本地内存?
假设我还想传递此数组的长度,然后将其添加const int length到内核的参数中,但是我不确定为什么要省略global限定符,除非我见过其他人这样做。毕竟,length所有工人都必须可以使用。如果我是对的,那么length将有一个通用的地址空间,但是同样,我真的不知道这意味着什么。
我希望有经验的人可以解决这个问题。这不仅对我来说很棒,但对希望获得一些有关GPU内存管理实践知识的其他发烧友,我也希望如此。
常量:所有工作者可见的一小部分缓存的全局内存。如果可以,请使用它,只读。
全局:慢,所有人都可以看到,可以读写。这是您所有数据都将结束的位置,因此始终需要对其进行一些访问。
本地:您是否需要在本地组中共享某些内容?使用本地!您所有的本地工作人员都访问相同的全局内存吗?使用本地!本地内存仅在本地工作人员内部可见,并且大小有限,但是速度非常快。
专用:仅对工作人员可见的内存,将其视为寄存器。默认情况下,所有未定义的值都是私有的。
假设我将一个long和length 10000类型的数组传递给内核,我将仅使用该数组进行读取,然后我将其声明为全局const,因为它必须对所有工作人员都可用并且不会更改。为什么不使用常量限定符?
实际上,是的,您可以并且应该使用constant限定符。这会将您的数据放在恒定内存中(一小部分只读内存,所有工作人员都可以快速访问)。GPU用来将制服转移到所有顶点着色器。
当通过CPU为该数组设置缓冲区时,实际上我也可以将数组设为只读,在我看来这与声明const相同。再说一遍,什么时候以及为什么要声明常量或全局const?
并非如此,当您创建只读缓冲区时,您仅打算对OpenCL进行只读设置,因此打算在后台进行优化,但实际上可以从内核写入该缓冲区。
global const只是对开发人员的一种保障,因此您不要无意间写一些内容,否则会在编译时出现错误。基本上,与普通C主机端计算相同。如果所有内存均为非常量,则程序也可以正常运行。
在执行内存密集型任务时,将阵列复制到内核内部的本地阵列会更好吗?我的猜测是本地内存太小,但是如果数组的长度只有10怎么办?阵列何时会过大/过小?更笼统:什么时候值得将数据从全局内存复制到本地内存?
只有所有工人都阅读它才值得。如果每个工作程序都读取全局内存的单个值,则不值得。在这里有用:
Worker0 -> Reads 0,1,2,3
Worker1 -> Reads 0,1,2,3
Worker2 -> Reads 0,1,2,3
Worker3 -> Reads 0,1,2,3
Run Code Online (Sandbox Code Playgroud)
在这里没有用:
Worker0 -> Reads 0
Worker1 -> Reads 1
Worker2 -> Reads 2
Worker3 -> Reads 3
Run Code Online (Sandbox Code Playgroud)
说我也想传递这个数组的长度,然后我将const int length添加到内核的参数中,但是我不确定为什么要省略全局限定符,除非我看到其他人这样做。毕竟,长度必须对所有工人都足够。如果我是对的,那么length将具有通用的地址空间,但是同样,我真的不知道这意味着什么。
如果您在内核参数中未指定限定词,则通常默认为constant,这是您希望这些小元素能够被所有工作人员快速访问的条件。
OpenCL编译器通常针对内核参数遵循的规则是:如果它仅读取并适合常量,常量或全局变量。
| 归档时间: |
|
| 查看次数: |
2433 次 |
| 最近记录: |