OpenCL从GPU读取可变大小的结果缓冲区

OpenCL从GPU读取可变大小的结果缓冲区,c,visual-studio-2013,opencl,gpu,nvidia,C,Visual Studio 2013,Opencl,Gpu,Nvidia,我有一个搜索OpenCL 1.1算法,它适用于少量数据: 1.)构建inputData数组并将其传递给GPU 2.)创建一个非常大的resultData容器(例如200000*sizeof(cl_uint))并传递这个容器 3.)创建resultSize容器(初始化为零),该容器可以通过原子操作访问(至少我这样认为) 当我的一个工作程序有一个结果时,它会将该结果复制到resultData缓冲区中,并在原子inc操作中增加resultSize(直到缓冲区已满) 让我写一个代码示例(opencl代码

我有一个搜索OpenCL 1.1算法,它适用于少量数据:

1.)构建inputData数组并将其传递给GPU

2.)创建一个非常大的resultData容器(例如200000*sizeof(cl_uint))并传递这个容器

3.)创建resultSize容器(初始化为零),该容器可以通过原子操作访问(至少我这样认为)

当我的一个工作程序有一个结果时,它会将该结果复制到resultData缓冲区中,并在原子inc操作中增加resultSize(直到缓冲区已满)

让我写一个代码示例(opencl代码):

在主机端,我读取缓冲区并将resultBufferSize设置为零:

resultBufferSize = 0;
oclErr |= clEnqueueWriteBuffer(gpuAcces.getCqCommandQueue(), cm_resultBufferSize,  CL_TRUE, 0,  sizeof(cl_uint), (void*)&resultBufferSize, 0, NULL, NULL);
现在我的问题是:

我有比resultData所能存储的结果多得多的结果。无论如何,我不知道结果的大小(例如,我能找到多少条路径)

我的想法:

我会不时清空(或处理)主机端的容器,并在缓冲区已满且工作人员将在一个while循环中等待时重置resultSize

我喜欢这个想法,因为我也可以在主机上并行处理数据

但我还无法实施任何解决方案:

1.)NVIDIA不能在无止境的情况下工作,或者至少我不能使用它。当我尝试使用无止境循环时,卡崩溃了

2.)barrier()和mem_fence()可以管理同步问题,但不能管理此问题

您是否知道我如何处理不固定的结果大小(例如,在搜索问题期间)?我几乎可以肯定一定有好的图案,但我找不到

NVIDIA opencl有睡眠吗?因为我会把它放进无休止的循环中,也许这对我有点帮助

我想可变的结果是一个老问题,必须有好的模式。
在我之前的帖子中,我也遇到了类似的问题(但上下文不同)。

关于不同的问题大小,我也遇到了类似的问题。一种方法是简单地实施分而治之的方法,并在主机上分割数据。您可以在设备上逐个处理数据块

顺便说一句:你对这个比较有把握吗


while(lastPosition**>**RESULT\u BUFFER\u SIZE)
您没有明确表示您正在使用Windows作为操作系统,但我认为这是因为您的问题中有VS2013标记


Nvidia卡不会崩溃。在Windows上,您可以在WDDM驱动程序中找到它,如果GPU驱动程序没有响应,它将重新启动。您可以使用Nsight轻松禁用此“功能”。但是,请注意,这可能会导致桌面环境出现问题,因此请确保编写的内核将在可容忍的时间内结束。然后,您甚至可以在使用Nvidias OpenCL实现的Windows上运行非常长的内核

为什么不使用
addr=原子添加(&addr\u计数器,1)操作,并使用返回的地址写入另一个全局缓冲区
缓冲区[addr*2]=X;缓冲区[addr*2+1]=Y

如果返回的地址大于缓冲区大小,则可以在空间不足时轻松检查

编辑:您想要的是并行内核执行和数据访问,这在OpenCL1.1中是不可能的。您应该选择具有该特性(SVM或管道)的OpenCL2.0

保持内核在while循环中检查变量,并且没有从主机端清空(访问变量)的机制。将使内核死锁,并使图形崩溃


如果您想坚持使用OpenCL1.1,唯一的方法就是运行许多小型内核,然后检查结果。在CPU中处理数据时,您可以并行启动更多内核。

您应该使用OpenCL2.0和管道;它们非常适合解决这类问题。

我使用的是NVIDIA,它仅支持opencl 1.1。相比之下,您的意思是什么#定义结果\u缓冲区\u大小20000为整数,lastPosition为uint。你认为这会导致问题吗?也许这也会是个问题。但我主要想知道,为什么要进行“比大”而不是“比小”的比较。因为在缓冲区溢出的情况下,我想等到缓冲区变为空,现在我完全理解了您的问题。因此,OpenCL设备必须被理解为一个封闭的计算单元,您无法避免外部CPU-GPU同步。这并没有改变我的建议,即事先分解你的数据。顺便说一句:如果这是一个优化问题,那么寻找top-k-解决方案是否有用,例如k-最短路径或类似的解决方案。另一个策略可能是实现输入或结果数据的压缩,如二进制编码?您的最后一句话似乎是非常好的替代解决方案。我一到家就要试一下,然后回来。我也要试一下,然后回来。我也非常感谢你。显然超时是我的主要问题。谢谢,我刚看了链接。嗨!我仍然有超时问题。也许我也应该在其他地方更改它?阅读评论我认为最好是启动更多次内核,因为在这种情况下,我不需要在GPU上进行任何同步。顺便说一句,我很抱歉NVIDIA不支持OpenCL2.0。。。
resultBufferSize = 0;
oclErr |= clEnqueueWriteBuffer(gpuAcces.getCqCommandQueue(), cm_resultBufferSize,  CL_TRUE, 0,  sizeof(cl_uint), (void*)&resultBufferSize, 0, NULL, NULL);