Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有人能解释一下这个OpenCL程序的错误吗?_C_Multithreading_Kernel_Opencl_Gpu - Fatal编程技术网

有人能解释一下这个OpenCL程序的错误吗?

有人能解释一下这个OpenCL程序的错误吗?,c,multithreading,kernel,opencl,gpu,C,Multithreading,Kernel,Opencl,Gpu,我在这里列出了我怀疑不正确的主机程序的主要部分: 我对指针还不是很在行,我想我可能把一些变量分配错了 这是一个内核程序,它应该给出我的程序试图做什么的想法: const char *KernelSource = "\n" "__kernel void sumElements( \n" " __global float* input, \n" " __global float output, \n

我在这里列出了我怀疑不正确的主机程序的主要部分:

我对指针还不是很在行,我想我可能把一些变量分配错了

这是一个内核程序,它应该给出我的程序试图做什么的想法:

    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";
const char*KernelSource=“\n”
“\uu内核无效元素(\n”
\u全局浮点*输入,\n
\u全局浮点输出,\n
“\uuu全局整数\N”
“{\n”
“int i=get_global_id(0);\n”
“如果(i

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

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

因此,将
\u全局浮点输出
更改为
\u全局浮点*输出
。然后在内核更改中:

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

if(i
您可能需要更改分配缓冲区的方式以使其正常工作,但我在OpenCL中这样做已经有很长一段时间了,我现在找到的文档没有显示缓冲区中的任何明显错误

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


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

因此,将
\u全局浮点输出
更改为
\u全局浮点*输出
。然后在内核更改中:

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

if(i
您可能需要更改分配缓冲区的方式以使其正常工作,但我在OpenCL中这样做已经有很长一段时间了,我现在找到的文档没有显示缓冲区中的任何明显错误

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


要解决这个问题,您需要使用OpenCL

来添加到Telgin的答案中,这样对单个元素求和是非常低效的(尽管使用原子操作在技术上是可以实现的)。您可能需要考虑减少问题:例如,如果输入具有N个元素,则创建I工作项,每个工作项负责汇总N/I元素,然后(i)输出部分和的数组,然后将其累积回主机(II)。使用OpenCL内存屏障,让一个工作项在输出单个值之前在设备上累积部分和。非常好!如您所述,将变量更改为指针。我认为有一个变量类型使它成为指针,在变量前面取消引用它?关于原子操作,你是对的。现在只剩1分了。我要读一些书。@Chucky是的,没错。在变量声明中使用*使其成为指针,然后对其使用*运算符,通过访问指针处的值来解除对它的引用。另外,James Beilby的观点是正确的,因为这是非常低效的,一旦你对它按预期工作感到满意,你就应该去阅读关于缩减的内容,使其更快。目前我得到了一个“原子添加/原子添加未定义”。我已经读到,不需要include语句,但应该在命令行中输入:$nvcc-arch=sm_11 glmax.cu-o glmax我在我的MacBook上尝试过,但没有识别出nvcc。你们两个知道OSX上原子操作是如何配置的吗?在Linux上,至少需要添加
#pragma OPENCL EXTENSION cl\u khr\u global\u int32\u base\u atomics:在内核的开头启用
,以启用一些原子。你试过了吗?OSX可能也是如此。再加上Telgin的答案,像这样对单个元素求和是非常低效的(尽管使用原子操作在技术上是可以实现的)。您可能需要考虑减少问题:例如,如果输入具有N个元素,则创建I工作项,每个工作项负责汇总N/I元素,然后(i)输出部分和的数组,然后将其累积回主机(II)。使用OpenCL内存屏障,让一个工作项在输出单个值之前在设备上累积部分和。非常好!如您所述,将变量更改为指针。我认为有一个变量类型使它成为指针,在变量前面取消引用它?关于原子操作,你是对的。现在只剩1分了。我要读一些书。@Chucky是的,没错。在变量声明中使用*使其成为指针,然后对其使用*运算符,通过访问指针处的值来解除对它的引用。另外,James Beilby是正确的,因为这是非常低效的,一旦你感到舒服,你就可以像