OpenCL:__ constant与__local?

时间:2013-03-06 21:28:44

标签: opencl gpgpu

假设我有一大堆值(仍小于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卡中运行。

1 个答案:

答案 0 :(得分:1)

首先,在第二种情况下,你应该为你的CPU提供结果。我假设您在计算后复制回global space

我认为这取决于你在内核中做了什么。例如,如果内核计算很重(每个线程有很多计算),那么第一个选项可能会付出代价。为什么?

  • 您花了一些时间将数据从global large空间复制到local空格leftright - 可接受
  • 您对本地空间的数据进行了大量计算 - 确定
  • 您需要花一些时间从local leftright复制回global large。 - 可接受。

但是如果内核相对较轻,即每个线程都会做一些小的计算,那么

  • 您使用constant空间的数据进行一些计算。这很可能意味着您不需要经常访问它。
  • 您可以将中间结果存储在本地空间中。
  • 您花了一些时间从local空间复制回global空间。 - 可接受。

总结一下大内核的第一个选择是更好的。对于小内核,第二个。

P.S。还有一点需要注意的是,如果你有多个内核一个接一个地在large上工作,那么肯定会选择第一个选项。因为这样您就可以将数据保存在全局内存空间中,并且每次启动内核时都不必进行复制。

编辑:既然你说过经常访问非常那么我认为你应该选择第一个选项。