0

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

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 写入上述一个变量。有可能做这样的事情吗?我需要得到数组中所有元素的总和。

4

1 回答 1

5

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

因此,更改__global float output__global float* output. 然后在您的内核更改中:

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

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

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

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

要解决此问题,您将需要使用 OpenCL原子操作。

于 2012-11-06T15:35:05.853 回答