OpenCV 具有gpu::Stream
封装异步调用队列的类。某些函数具有带有附加gpu::Stream
参数的重载。除了gpu-basics-similarity.cpp 示例代码之外,OpenCV 文档中关于如何以及何时使用的信息很少gpu::Stream
。例如,(对我来说)究竟是什么gpu::Stream::enqueueConvert
或gpu::Stream::enqueueCopy
做什么,或者如何gpu::Stream
用作附加重载参数并不是很清楚。我正在寻找一些类似教程的概述gpu::Stream
。
问问题
13340 次
1 回答
11
默认情况下,所有 gpu 模块功能都是同步的,即当前 CPU 线程被阻塞,直到操作完成。
gpu::Stream
是一个包装器cudaStream_t
,允许使用异步非阻塞调用。您还可以阅读“CUDA C 编程指南”了解有关 CUDA 异步并发执行的详细信息。
大多数 gpu 模块函数都有附加gpu::Stream
参数。如果您传递非默认流,则函数调用将是异步的,并且该调用将被添加到流命令队列中。
还提供了和gpu::Stream
之间的异步内存传输方法。但是异步内存传输仅适用于页面锁定的主机内存。还有另一个类封装了这种内存。CPU<->GPU
GPU<->GPU
CPU<->GPU
gpu::CudaMem
目前,如果相同的操作使用不同的数据排队两次到不同的流,您可能会遇到问题。某些函数使用常量或纹理 GPU 内存,下一次调用可能会在上一次调用完成之前更新内存。但是异步调用不同的操作是安全的,因为每个操作都有自己的常量缓冲区。对您持有的缓冲区的内存复制/上传/下载/设置操作也是安全的。
这是小样本:
// allocate page-locked memory
CudaMem host_src_pl(768, 1024, CV_8UC1, CudaMem::ALLOC_PAGE_LOCKED);
CudaMem host_dst_pl;
// get Mat header for CudaMem (no data copy)
Mat host_src = host_src_pl;
// fill mat on CPU
someCPUFunc(host_src);
GpuMat gpu_src, gpu_dst;
// create Stream object
Stream stream;
// next calls are non-blocking
// first upload data from host
stream.enqueueUpload(host_src_pl, gpu_src);
// perform blur
blur(gpu_src, gpu_dst, Size(5,5), Point(-1,-1), stream);
// download result back to host
stream.enqueueDownload(gpu_dst, host_dst_pl);
// call another CPU function in parallel with GPU
anotherCPUFunc();
// wait GPU for finish
stream.waitForCompletion();
// now you can use GPU results
Mat host_dst = host_dst_pl;
于 2013-07-25T09:30:04.007 回答