假设我有一大堆值(仍小于64 kB),内核中经常读取非常,但不会写入。然而,它可以从外部改变。该数组有两组值,让我们左右调用它们。 所以问题是,将大数组作为__global并将其写入__local left和__local右数组是否更快;或者将它作为常量__constant大并处理内核中的访问?例如:
__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];
}
VS
__kernel void f(__constant large, __global x, __global y) {
...
x = foo * large[idx];
y = bar * large[idx * offset];
}
(索引有点复杂,但可以用宏来制作,例如) 我读到恒定的记忆存在于全球空间中,所以它应该更慢吗? 它将在Nvidia卡中运行。
答案 0 :(得分:1)
首先,在第二种情况下,你应该为你的CPU提供结果。我假设您在计算后复制回global
space
。
我认为这取决于你在内核中做了什么。例如,如果内核计算很重(每个线程有很多计算),那么第一个选项可能会付出代价。为什么?
global large
空间复制到local
空格left
和right
- 可接受 local
left
和right
复制回global
large
。 - 可接受。但是如果内核相对较轻,即每个线程都会做一些小的计算,那么
constant
空间的数据进行一些计算。这很可能意味着您不需要经常访问它。 local
空间复制回global
空间。 - 可接受。总结一下大内核的第一个选择是更好的。对于小内核,第二个。
P.S。还有一点需要注意的是,如果你有多个内核一个接一个地在large
上工作,那么肯定会选择第一个选项。因为这样您就可以将数据保存在全局内存空间中,并且每次启动内核时都不必进行复制。