OpenCL:__常量vs.__本地?
假设我有一个很大的值数组(仍然小于64 kB),它通常在内核中读取,但不写入。然而,它可以从外部改变。数组有两组值,让我们分别称它们为left和right。 所以问题是,将大数组作为_全局数组并将其写入_局部左数组和_局部右数组是否更快;或者将其作为常量uu常量大并在内核中处理访问?例如:OpenCL:__常量vs.__本地?,opencl,gpgpu,Opencl,Gpgpu,假设我有一个很大的值数组(仍然小于64 kB),它通常在内核中读取,但不写入。然而,它可以从外部改变。数组有两组值,让我们分别称它们为left和right。 所以问题是,将大数组作为_全局数组并将其写入_局部左数组和_局部右数组是否更快;或者将其作为常量uu常量大并在内核中处理访问?例如: __kernel void f(__global large, __local left, __local right, __global x, __global y) { for(int i; i
__kernel void f(__global large, __local left, __local right, __global x, __global y) {
for(int i; i < size; i++) {
left[i] = large[i];
right[i] = large[i + offset];
}
...
x = foo * left[idx];
y = bar * right[idx];
}
(索引有点复杂,但可以用宏来创建)
我读到恒定的记忆存在于全球空间中,那么它应该慢一点吗?
它将在Nvidia卡中运行。首先,在第二种情况下,您应该有某种方法使结果可供您的CPU使用。我假设您在计算后复制回一个
全局
空间
我认为这取决于你在内核中做了什么。例如,如果您的内核计算量很大(每个线程都要进行大量计算),那么第一个选项可能会带来额外的开销。为什么?
- 您需要花费一些时间将数据从
复制到全局大空间
左侧空间和本地空间
-可以接受右侧空间
- 你对局部空间的数据做了大量的计算-好的
- 您需要花一些时间从
本地
和左侧
复制回右侧
全局
-可以接受大型
- 您可以使用
空间中的数据进行一些计算。这很可能意味着你不需要经常访问它李>常量
- 将中间结果存储在局部空间中
- 您需要花费一些时间从
空间复制回本地
空间。-可以接受全局
large
上工作,那么一定要选择第一个选项。因为这样您就可以将数据保存在全局内存空间中,而不必每次启动内核时都进行复制
编辑:既然你说它经常被访问,那么我想你应该选择第一个选项。嗨,谢谢,我明白你的意思,但是
left
和right
或large
的值不会复制回CPU。为了澄清这一点,请想象变量x
和y
是计算的对象,而大的
数组只是一些权重。x
和y
(不只是两个,有很多)在GPU上,内核被多次调用,最后只有x
和y
被读回CPU。哦,我明白了。那么选项二可能更好,因为全局内存中不需要“大”。大多数GPU都有专门的缓存,用于恒定的内存空间。所以它会有回报的。仅供参考,在OpenCL关键字之前不再需要两个下划线,“常量”现在与“常量”相同。另外,根据我的经验,大多数情况下,对于不太繁琐的算法,很难估计性能。更不用说一种架构的优化对另一种架构来说可能是噩梦。因此,要回答您的问题,您必须卷起袖子,同时实现并测试:)。非常感谢,我不知道“\uuuuu”是可选的,它肯定会节省一些工作。是的,我们把代码作为第一个选项来实现,并且正在讨论可能使用常量重新实现它,我想我们只需要尝试一下:P
__kernel void f(__constant large, __global x, __global y) {
...
x = foo * large[idx];
y = bar * large[idx * offset];
}