在输出缓冲区

时间:2015-11-03 11:36:50

标签: opencl

我是OpenCL的新手,但是使用opengl \ webgl工作了多年,用于绘图和GPGPU。

我想检查折线与其他人的交点。折线是一组连接的段 - 如LINE_STRIP。

我有折线。每条折线都有很多分。我把所有放在一个缓冲区。当缓冲区看起来像[pntsCount,x,y,x,y ....,pntsCount,x,y,....]时。 我们称之为 - 积分缓冲区。

另外,我有一个缓冲区,用于保存每条折线开头的索引,例如'pntsCount'值的索引。 让我们调用它 - 启动缓冲区

我的全局是折线的数量=启动缓冲区的长度。

在每个工作项中,我正在我当前的折线上运行(来自折线缓冲区)并检查与单折线的交点。

今天,我提供了启动缓冲区大小的内核输出缓冲区,用于保存是否存在交集。

这样,内核结束后。我正在运行主机中的缓冲区,并检查哪个具有true \ false值。

我的问题是, 我可以将我的真实结果堆叠在输出缓冲区中,而不是所有折线的真/假值。 我的意思是,在我的输出中仅保存与我的单个折线相交的折线的索引。

所以我的结果缓冲区将用于exmaple [4,24,10,...] 而不是[0,0,0,1,0,0,0,0,0,1 ....]

为此,我需要一个变量,它在结果缓冲区中保存当前索引以设置值,然后为下一个结果递增它。 在调用第一个内核之前,我需要将其设置为0。

我看到有一个atomic_inc,此外我可以通过本地记忆和障碍实现这一目标。

有人可以为我订购吗?也许是一个如何做到的例子?

1 个答案:

答案 0 :(得分:0)

瓶颈是什么?输出数据还是计算? 如果是计算,则采用原子方法。

你可以这样做:

  • 对全局变量使用atomic_inc(),获取返回值。并在该地址写入line_id或行数据本身。
  • 要进行额外的优化,请在本地收集所有真实的行,然后全局执行atomic_add(),然后将返回的值写入所有line_id或数据。

注意:原子函数返回操作前的值。 因此,如果你使用atomic_add(10),你将得到一个0,而下一个atomic_add()将得到10.因此,将该值用作写入内存区域的基址是非常有用的。

如果您决定写入数据。您最终会得到一个可以复制出来的打包结构。如果你写了id,你将不得不在以后发布它。取决于您可以选择一种或另一种方法的数据大小。

示例:

主机:

//Create a buffer to hold a counter
cl::Buffer counter(&context, CL_READ_WRITE, sizeof(cl_uint));

while(running){
    //Reset it
    cl_uint zero_counter = 0;
    queue.enqueueWriteBuffer(counter, CL_FALSE, 0, sizeof(cl_uint), &zero_counter);
    //Launch the kernel
    ...
    //Read it back
    cl_uint data_counter = 0;
    queue.enqueueReadBuffer(counter, CL_TRUE, 0, sizeof(cl_uint), &data_counter);
    //Read back other buffers using data_counter's returned value
    ...
}

设备:

__kernel mykern(__global uint * counter, ...){
    ...
    if(condition){ //Condition to add it to the output buffer
        uint addr = atomic_inc(counter);
        out[addr] = ... //Write it there
    }
}