C++ OpenCL代码不适用于较大的数据集

C++ OpenCL代码不适用于较大的数据集,c++,opencl,C++,Opencl,我试图在OpenCL/C++中编写排序函数和求和函数。然而,虽然这两个函数都可以在较小的数据集上正常工作,但它们都不能在任何显著长度的数据集上工作。我尝试使用的数据集长度约为200万个条目,但函数在大约500个条目时停止工作。如果您能提供帮助,我们将不胜感激。下面是OpenCL代码 编辑:现在仅显示与总和完全相关的代码(根据请求) 内核空和(全局常量双*A,全局双*B){ int id=获取全局id(0); int N=获取全局大小(0); B[id]=A[id]; 屏障(CLK_GLOBAL_

我试图在OpenCL/C++中编写排序函数和求和函数。然而,虽然这两个函数都可以在较小的数据集上正常工作,但它们都不能在任何显著长度的数据集上工作。我尝试使用的数据集长度约为200万个条目,但函数在大约500个条目时停止工作。如果您能提供帮助,我们将不胜感激。下面是OpenCL代码

编辑:现在仅显示与总和完全相关的代码(根据请求)

内核空和(全局常量双*A,全局双*B){
int id=获取全局id(0);
int N=获取全局大小(0);
B[id]=A[id];
屏障(CLK_GLOBAL_MEM_围栏);
对于(inti=1;i

和C++代码:

        std::vector<double> temps(100000, 1);

        // Load functions
        cl::Kernel kernel_sum = cl::Kernel(program, "sum");

        // Set up variables
        size_t elements = temps.size();
        size_t size = temps.size() * sizeof(double);
        
        size_t workgroup_size = 10;
        size_t padding_size = elements % workgroup_size;

        // Sum
        if (padding_size) {
            std::vector<double> temps_padding(workgroup_size - padding_size, 0);
            temps.insert(temps.end(), temps_padding.begin(), temps_padding.end());
        }

        std::vector<double> temps_sum(elements);
        size_t output_size = temps_sum.size() * sizeof(double);

        cl::Buffer sum_buffer_1(context, CL_MEM_READ_ONLY, size);
        cl::Buffer sum_buffer_2(context, CL_MEM_READ_WRITE, output_size);

        queue.enqueueWriteBuffer(sum_buffer_1, CL_TRUE, 0, size, &temps[0]);
        queue.enqueueFillBuffer(sum_buffer_2, 0, 0, output_size);

        kernel_sum.setArg(0, sum_buffer_1);
        kernel_sum.setArg(1, sum_buffer_2);
        
        queue.enqueueNDRangeKernel(kernel_sum, cl::NullRange, cl::NDRange(elements), cl::NDRange(workgroup_size));
        queue.enqueueReadBuffer(sum_buffer_2, CL_TRUE, 0, output_size, &temps_sum[0]);
        double summed = temps_sum[0];

        std::cout << "SUMMED: " << summed << std::endl;
std::向量temp(100000,1);
//荷载函数
cl::Kernel Kernel_sum=cl::Kernel(程序,“sum”);
//设置变量
大小元素=临时大小();
size\u t size=temps.size()*sizeof(双精度);
工作组规模=10;
大小\u t填充\u大小=元素百分比工作组\u大小;
//总数
如果(填充大小){
向量临时填充(工作组大小-填充大小,0);
插入(temps.end(),temps_padding.begin(),temps_padding.end());
}
std::向量时间和(元素);
size\u t output\u size=temps\u sum.size()*sizeof(双精度);
cl::Buffer sum\u Buffer\u 1(上下文、cl\u MEM\u只读、大小);
cl::Buffer sum\u Buffer\u 2(上下文、cl\u MEM\u读写、输出大小);
enqueueWriteBuffer(sum_buffer_1,CL_TRUE,0,size,&temps[0]);
enqueueFillBuffer(总和缓冲区2,0,0,输出大小);
kernel_sum.setArg(0,sum_buffer_1);
kernel_sum.setArg(1,sum_buffer_2);
enqueueNDRangeKernel(kernel_sum,cl::NullRange,cl::NDRange(元素),cl::NDRange(工作组大小));
enqueueReadBuffer(sum_buffer_2,CL_TRUE,0,output_size,&temps_sum[0]);
双重求和=临时求和[0];

std::cout您正试图使用障碍来实现跨工作组的同步。这行不通


工作组之间没有明确的顺序;您只能在工作组中使用这种简化算法。您可能需要使用第二个内核过程来组合来自各个工作组的结果,或者在主机CPU上执行这部分操作。(或者修改您的算法,以某种方式使用原子等)。

您正在尝试使用屏障来跨工作组进行同步。这行不通


工作组之间没有明确的顺序;您只能在工作组中使用这种简化算法。您可能需要使用第二个内核过程来组合来自各个工作组的结果,或者在主机CPU上执行这部分操作。(或者修改算法以某种方式使用原子等)

什么是“停止工作”呢?什么失败了?在哪里?本质上,排序不正确。它几乎是这样的——它有点像是在块中排序,所以前2/5被排序,最后2/5被排序,然后中间就是一团乱麻。对于求和,它只是求和不正确。我尝试了一种不同的求和方法,但是数字太高了,而在提供的方法中,结果太低了。你能把你的代码简化为一种不起作用的方法吗?这里的人不想通过你的论据处理和错误检查等。将它归结为几行C++和一个短的OpenCL内核,它们显示了你所看到的问题之一。我把所有的东西都包括进去了,这样人们就可以在他们希望的时候运行代码(尽管他们需要删除UTIL.H,哎哟)。老实说,我不知道问题出在哪里。我将把它简化为只显示求和的东西,但是是的,“停止工作”是什么意思?什么失败了?在哪里?本质上,排序不正确。它几乎是这样的——它有点像是在块中排序,所以前2/5被排序,最后2/5被排序,然后中间就是一团乱麻。对于求和,它只是求和不正确。我尝试了一种不同的求和方法,但是数字太高了,而在提供的方法中,结果太低了。你能把你的代码简化为一种不起作用的方法吗?这里的人不想通过你的论据处理和错误检查等。将它归结为几行C++和一个短的OpenCL内核,它们显示了你所看到的问题之一。我把所有的东西都包括进去了,这样人们就可以在他们希望的时候运行代码(尽管他们需要删除UTIL.H,哎哟)。老实说,我不知道问题出在哪里。我会简化它,只显示求和的东西,但是是的。
        std::vector<double> temps(100000, 1);

        // Load functions
        cl::Kernel kernel_sum = cl::Kernel(program, "sum");

        // Set up variables
        size_t elements = temps.size();
        size_t size = temps.size() * sizeof(double);
        
        size_t workgroup_size = 10;
        size_t padding_size = elements % workgroup_size;

        // Sum
        if (padding_size) {
            std::vector<double> temps_padding(workgroup_size - padding_size, 0);
            temps.insert(temps.end(), temps_padding.begin(), temps_padding.end());
        }

        std::vector<double> temps_sum(elements);
        size_t output_size = temps_sum.size() * sizeof(double);

        cl::Buffer sum_buffer_1(context, CL_MEM_READ_ONLY, size);
        cl::Buffer sum_buffer_2(context, CL_MEM_READ_WRITE, output_size);

        queue.enqueueWriteBuffer(sum_buffer_1, CL_TRUE, 0, size, &temps[0]);
        queue.enqueueFillBuffer(sum_buffer_2, 0, 0, output_size);

        kernel_sum.setArg(0, sum_buffer_1);
        kernel_sum.setArg(1, sum_buffer_2);
        
        queue.enqueueNDRangeKernel(kernel_sum, cl::NullRange, cl::NDRange(elements), cl::NDRange(workgroup_size));
        queue.enqueueReadBuffer(sum_buffer_2, CL_TRUE, 0, output_size, &temps_sum[0]);
        double summed = temps_sum[0];

        std::cout << "SUMMED: " << summed << std::endl;