小编Spr*_*son的帖子

即使输出数据要发送到 OpenGL 而不是 CPU,是否应该等待 CUDA 流完成?

这是一个普遍的问题,虽然我使用 OpenCV 作为框架,但这个问题比 OpenCV 的领域更广泛。

我正在开发一个图像处理工具,它将有效地从网络摄像头获取图像(产生位于主机内存cv::Mat),将其上传到 CUDA 中的 GPU 设备内存(即cv::GpuMat),使用 CUDA 进行一些处理并获得结果finalCudaMat,最后发送结果传送至 OpenGL(即cv::ogl::Buffer::mapDevice+ finalCudaMat.copyTo(mappedOglBuffer))。一切都按预期进行。

由于整个过程涉及多个步骤,因此我使用 CUDA 流对象 ( cv::cuda::Stream) 来使 CUDA 调用异步,而不是等待 CPU 端完成每个操作。现在,如果有人最终将结果复制到 CPU 矩阵(即finalCudaMat.download(finalCpuMat)),如在通常情况下,通常需要等待流(cudaStream.waitForCompletion())以确保结果在使用 CPU 端矩阵之前准备就绪。

就我而言,结果永远不会返回到 CPU,因为它继续在屏幕上渲染(还涉及一些 OpenGL 操作和着色器)。

  • 一种方法是,在开始将 GpuMat 复制到 OpenGL 缓冲区之前,等待 CUDA 工作完成可能是合适的。因此,如果我添加流等待,一切都会正常工作,CUDA 操作大约需要 2.5 毫秒。

  • 另一种方式,感觉就像我不需要等待流的完成(无论如何,所有结果都被 GPU 消耗——CPU 永远不会再参与)。cudaStream.waitForCompletion()因此,我可以在执行之前删除呼叫finalCudaMat.copyTo(mappedOglBuffer),一切似乎都工作正常。整个 CUDA 处理操作(基本上任何 GPU 任务减去 OpenGL 相关的任务)显然对我来说大约需要 1.8 毫秒。

过去,如果涉及两个不同的 API,我有过无法正确同步 GPU 工作的糟糕经历(例如,在 Direct3D 9 …

opengl opencv cuda gpu direct3d

5
推荐指数
1
解决办法
588
查看次数

标签 统计

cuda ×1

direct3d ×1

gpu ×1

opencv ×1

opengl ×1