【问题标题】:Computing on variable length arrays in OpenCL在 OpenCL 中计算可变长度数组
【发布时间】:2017-05-01 16:53:52
【问题描述】:

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

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

【问题讨论】:

    标签: multithreading kernel opencl gpgpu c99


    【解决方案1】:

    您可以将任何缓冲区传递给内核,内核不需要全部使用它。 例如,如果您的内核减少了一个缓冲区,您可以在运行时使用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);
    }
    

    【讨论】:

    • 所以我不能很容易地从 khronos 规范中分辨出来,但是 get_global_size(n) 是否从 globalWorkSize [ ] 中获取元素 n?以及如何使用get_global_size() 函数来完成不同的事情?您知道的任何教程或示例都会有所帮助。我理想的情况是传递大量数组常量,每个数组都包含可变长度数组。我的想法是通过用零填充来标准化数组的长度并将其折叠成一个非常大的数组,然后在内核中使用模运算符来推导数组变化的位置。但这对记忆来说似乎很昂贵?谢谢
    • 您不需要在单个数组中传递所有数据,如果需要,您可以将其分隔在不同的数组中。如果您需要对不同的数组执行不同的操作,则将它们分隔在不同的内核中。在单个内核中传递 20 个具有 20 个不同长度的缓冲区来执行 20 个不同的进程不仅难以做到而且不是最优的,因为您将有许多代码路径来实现它。我在代码中描述的是一个示例内核,它对缓冲区进行处理,大小在执行时已知并且没有分支。
    • 嗯,我正在对 5 个不同的时间段进行移动平均/偏差,大概有十亿个数据点。我试图想出一些聪明的方法来避免必须为每个数据点调用内核(因为平均值基于以前的数据点),因为我确信这具有不错的开销价格。就像我说的那样,我的想法是将多个示例分别折叠到不同的时间段数组中,然后使用整数 div 执行。我会测试性能看看。还想我可以在工作组/维度/其他方面做点什么,但我还没有受过足够的教育
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    • 2012-12-04
    • 2020-11-20
    相关资源
    最近更新 更多