我是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,此外我可以通过本地记忆和障碍实现这一目标。
有人可以为我订购吗?也许是一个如何做到的例子?
答案 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
}
}