OpenCL何时使用全局,私有,本地,常量地址空间

时间:2017-07-31 22:25:23

标签: memory opencl memory-address

我正在尝试学习OpenCL,但我很难决定使用哪些地址空间,因为我只找到组合资源来声明这些地址空间是什么,而不是为什么它们存在或何时使用它们。资源至少过于分散,所以有了这个问题,我希望收集所有这些信息:什么是地址空间,它们为什么存在,何时使用哪个地址空间以及有关内存的优缺点是什么?性能

据我所知(可能过于简化),GPU有两种物理类型的内存:全局内存,远离实际的处理器,所以很慢但很大,可供所有工作人员使用和本地内存,靠近实际处理器,速度快但很小,无法从其他工作人员访问。

直观地说,local限定符确保将变量放在本地内存中,global限定符确保将变量放在全局内存中,但我不确定这究竟是什么。这会留下privateconstant限定符。那些人的目的是什么?

还有一些隐含的限定词。例如,我认为the specifications提到通用地址空间,它用于没有限定符的参数。这究竟是做什么的?然后还有局部函数变量。那些地址空间是什么?

这是一个使用我的直觉的例子,但不知道我在做什么:

示例: 假设我将类型long和长度10000的数组传递给我将只用于读取的内核,然后我将其声明为global const,因为它必须可供所有工作人员使用,并且不会更改。为什么我不使用constant限定符?当通过CPU为这个数组设置缓冲区时,我实际上也可以将数组设为只读,这在我看来就像声明它const一样。那么,我何时以及为什么要声明constantglobal const

执行内存密集型任务时,将数组复制到内核中的本地数组会更好吗?我的猜测是本地内​​存太小了,但如果数组的长度只有10呢?阵列什么时候太大/太小?更一般:何时值得将数据从全局内存复制到本地内存?

说我也想传递这个数组的长度,然后我会将const int length添加到我的内核的参数中,但我不确定为什么我会省略global限定符,除非因为我见过其他人这样做。毕竟,所有工作人员都必须能够访问length。如果我是对的,那么length会有一个通用的地址空间,但我再也不知道这意味着什么。

我希望有经验的人可以清楚这一点。这对我来说不仅不错,而且我希望其他爱好者也希望获得有关GPU内存管理的实用知识。

1 个答案:

答案 0 :(得分:5)

常量:所有工作人员都可以看到一小部分缓存的全局内存。如果可以,请使用它,只读。

全局:慢,可见所有人,读或写。这是所有数据都将结束的地方,因此有些访问它总是必要的。

本地:您是否需要在本地群组中分享内容?使用本地!您所有本地工作人员是否都访问相同的全局内存?使用本地! 本地内存仅在本地工作人员中可见,并且大小有限,但速度非常快。

私有:仅对工作人员可见的内存,将其视为寄存器。默认情况下,所有未定义的值都是私有的。

  

假设我将一个long和long 10000类型的数组传递给我的内核   只会用来读取,然后我会声明它必须是全局const   适用于所有工人,不会改变。我为什么不用   常数限定符?

实际上,是的,您可以使用constant限定词。将数据放在常量内存中(所有工作人员都可以快速访问一小部分只读内存)。 GPU使用它将制服传输到所有顶点着色器。

  

通过CPU设置此阵列的缓冲区时,我实际上也是   只是可以让数组只读,这在我看来是这样的   和声明它一样。所以,我何时以及为什么要宣布   某些常量或全局常量?

不是真的,当你创建一个缓冲区只读时你只是指定OpenCL你打算只读它,所以它可以在后面做优化,但你实际上可以从内核写入它。 global const只是开发人员的安全保障,因此您不会意外地写入它,它会在编译时出错。 基本上,与普通C主机端计算相同。如果所有内存都是非常量的,程序也可以正常工作。

  

执行内存密集型任务时,将数组复制到内核中的本地数组会更好吗?我的猜测是本地内​​存太小了,但如果数组的长度只有10呢?阵列什么时候太大/太小?更一般:何时值得将数据从全局内存复制到本地内存?

只有所有工人都阅读它才有价值。如果每个worker读取全局内存的单个值,那么它就不值得。 在这里有用:

Worker0 -> Reads 0,1,2,3
Worker1 -> Reads 0,1,2,3
Worker2 -> Reads 0,1,2,3
Worker3 -> Reads 0,1,2,3

这里没用:

Worker0 -> Reads 0
Worker1 -> Reads 1
Worker2 -> Reads 2
Worker3 -> Reads 3
  

说我也想传递这个数组的长度,然后我会添加   const int length到我内核的参数,但我不确定为什么我   除了因为我见过其他人之外,我们会省略全局限定符   人们这样做。毕竟,所有工人都必须能够获得长度。如果   我是对的,那么长度会有一个通用的地址空间,但是,   我真的不知道这意味着什么。

如果你没有在内核参数中指定一个限定符,它通常默认为constant,这是你想要的那些小元素,让所有工人都可以快速访问。

OpenCL编译器通常遵循的内核参数规则是:如果它只读取并适合常量,常量,否则全局。