我有一个搜索OpenCL 1.1算法,该算法适用于少量数据:
1。)构建 inputData 数组并将其传递给GPU
2。)创建一个非常大的 resultData 容器(例如200000 * sizeof(cl_uint))并传递这个容器
3.。)创建 resultSize 容器(inited为零),可以通过原子操作访问(至少我猜这个)
当我的一个工人有结果时,它会将其复制到 resultData 缓冲区中,并在原子inc操作中递增 resultSize (直到缓冲区已满)。
让我编写一个代码示例(opencl代码):
lastPosition = atomic_add(resultBufferSize, 5);
while (lastPosition > RESULT_BUFFER_SIZE)
{
lastPosition = atomic_add(resultBufferSize, 5);
}
在主机端我读取缓冲区并将 resultBufferSize 设置为零:
resultBufferSize = 0;
oclErr |= clEnqueueWriteBuffer(gpuAcces.getCqCommandQueue(), cm_resultBufferSize, CL_TRUE, 0, sizeof(cl_uint), (void*)&resultBufferSize, 0, NULL, NULL);
现在我的问题是:
我的结果比resultData可以存储的结果多得多。无论如何,我不知道结果的大小(例如我可以找到多少路径)。
我的想法:
我会在主机端清空(或处理)容器并在缓冲区已满时重置 resultSize 并且工作人员将在中等待循环。
我喜欢这个想法,因为我也可以在主机上并行处理数据。
但是我还没有为此实现任何解决方案:
1。)NVIDIA无法无休止地工作,或者至少我无法使用它。当我尝试使用无限循环时,卡崩溃了。
2。)barrier()anf mem_fence()可以管理同步问题但不能管理这个问题
您是否有任何强大的想法如何处理不能修复结果大小(例如在搜索问题期间)?我几乎可以肯定必须有一个好的模式,但我找不到它。
NVIDIA opencl有没有睡觉?因为我会把它放到无限循环中,这可能对我有所帮助。
我猜变量结果是一个老问题,必须有好的模式。 我在之前的帖子中遇到了类似的问题(但背景不同)。
答案 0 :(得分:0)
我有一个关于变量问题大小的类似问题。一种方法是简单地实施分而治之的方法并在主机上分割数据。您可以在设备上一个接一个地处理数据块。
BTW:你确定比较
while (lastPosition **>** RESULT_BUFFER_SIZE)
答案 1 :(得分:0)
您还没有明确表示您使用Windows作为操作系统,但我认为,因为您的问题中包含VS2013标记。
Nvidia卡不会崩溃。在Windows上,您在WDDM驱动程序中有Timeout Detection & Recovery (TDR),如果GPU驱动程序没有响应,它将重新启动GPU驱动程序。您可以轻松地使用Nsight禁用此“功能”。但是,请注意,这可能会导致桌面环境出现问题,因此请确保编写的内核将在可容忍的时间内结束。然后,即使在具有Nvidias OpenCL实现的Windows上,您也可以运行非常长的内核。
答案 2 :(得分:0)
为什么不在全局变量上使用addr = atomic_add(&addr_counter, 1);
,并使用返回的地址写入另一个全局缓冲区buffer[addr*2] = X; buffer[addr*2+1] = Y;
。
如果返回的地址大于缓冲区大小,您可以轻松检查空间何时用完。
编辑:您想要的是并行内核执行和数据访问,这是OpenCL 1.1无法实现的。您应该选择具有该功能的OpenCL 2.0(SVM或管道)。
保持内核在while循环中检查变量,而没有从主机端清空(访问变量)的机制。会使你的内核陷入僵局,并使你的图形崩溃。
如果你想坚持使用OpenCL 1.1,唯一的办法就是运行许多小型内核,然后检查结果。您可以在CPU中处理数据时并行启动更多内核。
答案 3 :(得分:0)
你应该使用OpenCL 2.0和Pipes;他们非常适合这种问题。