【问题标题】:Can someone explain what is wrong with this OpenCL program?有人可以解释这个 OpenCL 程序有什么问题吗?
【发布时间】:2012-10-26 13:30:42
【问题描述】:

我已经包含了主机程序的主要部分,我怀疑这里是不正确的:

http://pastebin.com/qVkv9E11

我对指针还不是很擅长,我认为我可能错误地分配了一些变量。

这是内核程序,它应该可以让您了解我的程序正在尝试做什么:

    const char *KernelSource =           "\n"
"__kernel void sumElements(           \n"
"   __global float* input,            \n"
"   __global float output,            \n"
"   __global int N)                   \n"
"{                                    \n"
"   int i = get_global_id(0);         \n"
"   if(i < N)                         \n"
"       output += input[i];           \n"
"}                                    \n"
"\n";

也许这是导致错误的原因,因为我从未尝试过 SIMT 写入上述一个变量。有可能做这样的事情吗?我需要得到数组中所有元素的总和。

【问题讨论】:

    标签: c multithreading kernel opencl gpu


    【解决方案1】:

    如果你想真正读回输出的值,那么你也需要将它声明为一个指针。现在输出的值作为内核参数被复制进来,但是在内核结束后,您对其所做的任何更改都会被忽略。

    所以,将__global float output 更改为__global float* output。然后在您的内核更改中:

    if(i < N)
        output += input[i];
    

    if(i < N)
        *output += input[i];
    

    您可能需要更改分配缓冲区的方式才能使其正常工作,但是自从我在 OpenCL 中完成此操作以来已经很长时间了,而且我现在找到的文档没有显示任何明显的缓冲区中的错误。

    这里警告一句:加法不是原子操作。使用这种设置,总是会发生两个或多个线程读取 *output 的值,然后尝试在不同阶段将 *output + 1 写回它。因此,*output 的值会小于应有的值。

    要解决此问题,您需要使用 OpenCL atomic operations.

    【讨论】:

    • 只是为了补充 Telgin 的答案,像这样对单个元素求和是非常低效的(尽管在技术上使用原子操作可以实现)。您可能需要考虑减少问题:例如,如果您的输入有 N 个元素,则创建 I 个工作项,每个负责对 N/I 个元素求和,然后(i)输出一个部分和数组,然后在主机 (ii) 使用 OpenCL 内存屏障并让一个工作项在输出单个值之前在设备上累积部分总和。
    • 太棒了!如您所述,将变量更改为指针。我认为它有 * 成功的变量类型使其成为指针并在变量之前取消引用它?你对原子操作是正确的。现在才回来1。我会做一些阅读。
    • @Chucky 是的,没错。在变量声明中使用 * 使其成为指针,然后在其上使用 * 运算符通过访问指针处的值来取消引用它。此外,James Beilby 是正确的,因为这是非常低效的,一旦您对按预期工作感到满意,您应该阅读有关减少的内容以使其更快。
    • 目前我得到一个“atomicAdd/atomic_add 未定义”。我已经读到不需要包含语句,而是应该在命令行中输入: $nvcc -arch=sm_11 glmax.cu -o glmax 我在我的 MacBook 上尝试过,但无法识别 nvcc。你们有谁知道在 OSX 上是如何配置原子操作的吗?
    • 在 Linux 上,您至少需要在内核开头添加 #pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable 以启用一些原子。你试过吗? OSX 可能也是这样。
    猜你喜欢
    • 2020-05-02
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多