在OpenCL中计算可变长度数组

时间:2016-12-15 23:43:22

标签: multithreading kernel opencl gpgpu c99

我正在使用OpenCL(Xcode,Intel GPU),我正在尝试实现计算移动平均值和偏差的内核。我想将几个不同长度的双数组传递给内核。这是可以实现的,还是我需要用零填充较小的数组,以便所有数组都是相同的大小?

我是OpenCL和GPGPU的新手,所以请原谅我对任何命名法的无知。

1 个答案:

答案 0 :(得分:2)

你可以将任何缓冲区传递给内核,内核不需要全部使用它。 例如,如果内核减少了缓冲区,则可以使用get_global_size(0)在运行时查询工作项(要减少的项)的数量。然后使用适当的参数调用内核。

一个例子(未经优化):

__kernel reduce_step(__global float* data)
{
    int id = get_global_id(0);
    int size = get_global_size(0);
    int size2 = size/2;
    int size2p = (size+1)/2;
    if(id<size2) //Only reduce up to size2, the odd element will remain in place
       data[id] += data[id+size2p];
}

然后你就可以这样称呼它。

void reduce_me(std::vector<cl_float>& data){
    size_t size = data.size();

    //Copy to a buffer already created, equal or bigger size than data size
    // ... TODO, check sizes of buffer or change the buffer set to the kernel args.
    queue.enqueueWriteBuffer(buffer,CL_FALSE,0,sizeof(cl_float)*size,data.data());

    //Reduce until 1024
    while(size > 1024){
        queue.enqueueNDRangeKernel(reduce_kernel,cl::NullRange,cl::NDRange(size),cl::NullRange);
        size /= 2; 
    }

    //Read out and trim
    queue.enqueueReadBuffer(buffer,CL_TRUE,0,sizeof(cl_float)*size,data.data());
    data.resize(size);
}