如何在OpenCL中使用本地内存?

spl*_*cer 42 opencl

我最近一直在玩OpenCL,我能够编写只使用全局内存的简单内核.现在我想开始使用本地内存,但我似乎无法弄清楚如何使用get_local_size()和一次get_local_id()计算一个"块"输出.

例如,假设我想将Apple的OpenCL Hello World示例内核转换为使用本地内存的内容.你会怎么做?这是原始的内核源代码:

__kernel square(
    __global float *input,
    __global float *output,
    const unsigned int count)
{
    int i = get_global_id(0);
    if (i < count)
        output[i] = input[i] * input[i];
}
Run Code Online (Sandbox Code Playgroud)

如果这个例子不能轻易转换成显示如何使用本地内存的东西,那么任何其他简单的例子都可以.

Tom*_*Tom 31

查看NVIDIA或AMD SDK中的示例,它们应该指向正确的方向.例如,矩阵转置将使用本地存储器.

使用平方内核,可以在中间缓冲区中暂存数据.请记住传入附加参数.

__kernel square(
    __global float *input,
    __global float *output,
    __local float *temp,
    const unsigned int count)
{
    int gtid = get_global_id(0);
    int ltid = get_local_id(0);
    if (gtid < count)
    {
        temp[ltid] = input[gtid];
        // if the threads were reading data from other threads, then we would
        // want a barrier here to ensure the write completes before the read
        output[gtid] =  temp[ltid] * temp[ltid];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您可以使用限定符"__local"将变量声明为local.例如,您可以执行`__local float values [GROUP_SIZE];`然后让每个线程写入`values [get_local_id(0)] = ...`.不需要通过传入内核的指针来访问本地内存. (9认同)
  • 感谢您在上次编辑中添加代码!我似乎无法使你的内核正常工作....我如何使用clSetKernelArg()进行临时工作?我是否需要对临时使用clCreateBuffer()?另外,你的内核中有一些拼写错误:"temp*temp"应该是"temp [ltid]*temp [ltid]",并且应该在最后一行之前插入一个右括号. (7认同)
  • 我已经阅读了NVIDIA的介绍材料,我仍然觉得这些例子过于复杂.我正在寻找一个简单的1维示例,使用本地记忆来弄湿我的脚. (4认同)
  • 我纠正了错别字 - 在ipod上打字是正确的.你的clSetKernelArg没有分配足够的内存,你需要为每个线程一个cl_float空间(你只分配了一个浮点数).尝试:`clSetKernelArg(kernel,2,sizeof(cl_float)*local_work_size [0],NULL);`其中`local_work_size [0]`是维度0中的工作组大小. (3认同)

Ric*_*wig 28

如果本地内存的大小不变,还有另一种可能性.不使用kernels参数列表中的指针,只需通过声明__local即可在内核中声明本地缓冲区:

__local float localBuffer[1024];
Run Code Online (Sandbox Code Playgroud)

由于clSetKernelArg调用较少,因此会删除代码.


小智 5

在OpenCL中,本地内存用于在工作组中的所有工作项之间共享数据.并且它通常需要在可以使用本地存储器数据之前执行屏障调用(例如,一个工作项想要读取由其他工作项写入的本地存储器数据).屏障在硬件方面代价高昂.请记住,本地内存应该用于重复数据读/写.应尽可能避免银行冲突.

如果你不小心使用本地内存,那么使用全局内存可能会导致性能下降.