OpenCL - 迭代更新GPU内存缓冲区?

3
我需要一个OpenCL内核迭代更新缓冲区并返回结果。具体来说:
  1. 将初始缓冲区发送到内核
  2. 内核/工作器更新缓冲区中的每个元素
  3. 主机代码读取结果 - 希望能异步地进行,尽管我不确定如何在不阻塞内核的情况下实现这一点。
  4. 内核再次运行,再次更新每个元素,但新值取决于先前的值。
  5. 重复固定数量的迭代。
到目前为止,我已经通过提供输入和输出缓冲区来模拟此过程,当内核执行完成时将输出复制回输入,并重新启动内核。这似乎是非常浪费时间和滥用有限的内存带宽,因为缓冲区相当大(约1GB)。
有什么建议/示例吗?我在OpenCL方面还很新手,所以这可能有一个非常简单的答案。
如果有关系的话,我正在使用Cloo/OpenCL.NET在NVidia GTX460和两个GTX295上。

你能详细说明一下你是如何让它工作的吗? - AbiusX
2个回答

4
我建议你在设备中创建一个cl_mem。将数据复制到其中,然后使用内核进行迭代操作。使用相同的内存来存储结果会更容易,因为你的内核只需要一个参数。
然后,你只需要将数据复制到cl_mem中,并运行内核。之后,从设备中提取数据,并再次运行内核。
如果你不关心这个迭代是否会有一些来自下一个迭代的数据,你可以通过使用事件和OUT_OF_ORDER_QUEUE来大幅提高性能。这样,当你复制数据回来时,内核可以继续运行。

2

您可以将初始数据写入设备并使用内核更改其内容。一旦内核完成迭代,您可以读取相同的内存缓冲区并为下一个迭代重新启动内核。数据可以留在OpenCL设备上,无需再次发送到设备。

据我所知,没有方法可以在主机和设备之间同步工作。您只能启动内核并等待其返回。然后读取结果并重新开始。异步读取可能不安全,因为您可能会获得不一致的结果。


1
你不会有这方面的例子吧?每当我尝试从正在读取的任何内容中写入时,就会出现错误。 - 3Dave
抱歉,我没有样本。很高兴听到它起作用了。不客气! - Rick-Rainer Ludwig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接