gpt4 book ai didi

memory - OpenCL 何时使用全局、私有(private)、本地、常量地址空间

转载 作者:行者123 更新时间:2023-12-05 00:50:48 32 4
gpt4 key购买 nike

我正在尝试学习 OpenCL,但我很难决定使用哪些地址空间,因为我只发现组装资源声明了这些地址空间是什么,而不是为什么它们存在或何时使用它们。资源至少太分散了,所以我希望通过这个问题来收集所有这些信息:所有的地址空间是什么,它们为什么存在,何时使用哪个地址空间以及在内存和性能方面的优缺点是什么。
据我了解(这可能过于简化),GPU 有两种物理类型的内存:全局内存,远离实际处理器,速度慢但相当大,可供所有工作人员使用,以及本地内存,接近实际处理器,速度如此之快,但体积很小,其他工作人员无法访问。
直观地说,local限定符确保变量放置在本地内存中,global qualifier 确保将变量放置在全局内存中,尽管我不确定这正是发生的情况。这留下了privateconstant限定词。那些目的是什么?
还有一些隐含的限定符。例如,the specifications提到通用地址空间,我认为它用于没有限定符的参数。这到底是做什么的?然后还有局部函数变量。这些地址空间是什么?
这是一个使用我的直觉的例子,但不知道我实际上在做什么:
示例:
假设我传递了一个 long 类型的数组并且长度为 10000 到一个我只会用来读取的内核,然后我会声明它 global const因为它必须可供所有 worker 使用,并且不会改变。为什么我不使用 constant预选赛?通过 CPU 为这个数组设置缓冲区时,我实际上也可以将数组设为只读,在我看来这与声明它 const 相同。 .再说一次,我何时以及为什么要声明 constantglobal const ?
在执行内存密集型任务时,将数组复制到内核内部的本地数组会更好吗?我的猜测是本地内​​存太小了,但是如果数组只有 10 的长度呢?数组什么时候会太大/太小?更笼统地说:什么时候值得将数据从全局内存复制到本地内存?
假设我也想传递这个数组的长度,那么我会添加 const int length我的内核的论点,但我不确定为什么我会省略 global限定词除非因为我看到其他人这样做。毕竟,length必须可供所有 worker 使用。如果我是对的,那么 length会有一个通用的地址空间,但同样,我真的不知道这意味着什么。
我希望有经验的人可以解决这个问题。这不仅对我来说很棒,而且我也希望对其他想要获得有关 GPU 内存管理的实用知识的爱好者也有帮助。

最佳答案

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

全局:慢,所有人都能看到,读或写。它是您所有数据的终点,因此始终需要对其进行一些访问。

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

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

Say I pass an array of type long and length 10000 to a kernel which I will only use to read, then I would declare it global const as it must be available to all workers and it will not change. Why wouldn't I use the constant qualifier?



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

When setting the buffer for this array via the CPU, I actually also just could have made the array read-only, which in my eyes says the same as declaring it const. So again, when and why would I declare something constant or global const?



并非如此,当您创建一个只读缓冲区时,您只是指定 OpenCL 您计划以只读方式使用它,因此它可以在后面进行优化,但您实际上可以从内核写入它。 global const只是对开发者的一种保障,所以你不要不小心写到它,它会在编译时出错。
基本上,与普通 C 主机端计算相同。如果所有内存都是非常量的,程序也可以正常工作。

When performing memory-intensive tasks, would it be better to copy the array to a local array inside the kernel? My guess is that local memory would be too small, but what if the array only had a length of 10? When would the array be too big/small? More general: when is it worth copying data from global to local memory?



只有所有 worker 都阅读它才有值(value)。如果每个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

Say I also want to pass the length of this array, then I would add const int length to the arguments of my kernel, but I'm unsure why I would omit the global qualifier except because I have seen other people do it. After all, length must be accessible for all workers. If I'm right, then length would have a generic address space, but again, I don't really know what that means.



当您没有在内核参数中指定限定符时,它通常默认为 constant ,这就是你想要的那些小元素,让所有工作人员都能快速访问。

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

关于memory - OpenCL 何时使用全局、私有(private)、本地、常量地址空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45426212/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com