如何在OpenCV中使用gpu :: Stream? [英] how to use gpu::Stream in OpenCV?

查看:2418
本文介绍了如何在OpenCV中使用gpu :: Stream?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

OpenCV具有封装异步调用队列的 gpu :: Stream 类。一些函数具有额外的 gpu :: Stream 参数的重载。除了 gpu-basics-similarity.cpp示例代码,OpenCV文档中有关如何和何时使用 gpu :: Stream 的信息非常少。例如,对于 gpu :: Stream :: enqueueConvert gpu :: Stream :: enqueueCopy do,或者如何使用 gpu :: Stream 作为额外的重载参数。我正在寻找 gpu :: Stream 的教程式概述。

OpenCV has gpu::Stream class that encapsulates a queue of asynchronous calls. Some functions have overloads with the additional gpu::Stream parameter. Aside from gpu-basics-similarity.cpp sample code, there is very little information in OpenCV documentation on how and when to use gpu::Stream. For example, it is not very clear (to me) what exactly gpu::Stream::enqueueConvert or gpu::Stream::enqueueCopy do, or how to use gpu::Stream as additional overload parameter. I'm looking for some tutorial-like overview of gpu::Stream.

推荐答案

默认情况下,所有gpu模块函数都是同步的,即当前CPU线程被阻塞,直到操作完成。

By default all gpu module functions are synchronous, i.e. current CPU thread is blocked until operation finishes.

gpu :: Stream 是包含 cudaStream_t 并允许使用异步非阻塞调用。

gpu::Stream is a wrapper for cudaStream_t and allows to use asynchronous non-blocking call. You can also read "CUDA C Programming Guide" for detailed information about CUDA asynchronous concurrent execution.

大多数gpu模块函数都有额外的 gpu :: Stream 参数。如果传递非默认流,函数调用将是异步的,并且调用将被添加到流命令队列。

Most gpu module functions have additional gpu::Stream parameter. If you pass non-default stream the function call will be asynchronous, and the call will be added to stream command queue.

还有 gpu :: Stream CPU < - > GPU GPU 。但 CPU 异步存储器传输仅与页锁定主机存储器一起工作。还有另一个类 gpu :: CudaMem 来封装这样的内存。

Also gpu::Stream provides methos for asynchronous memory transfers between CPU<->GPU and GPU<->GPU. But CPU<->GPU asynchronous memory transfers works only with page-locked host memory. There is another class gpu::CudaMem that encapsulates such memory.

目前,被不同的数据入队两次到不同的流。一些函数使用常量或纹理GPU内存,并且下一个调用可以在上一个调用完成之前更新存储器。但是异步调用不同的操作是安全的,因为每个操作都有自己的常量缓冲区。

Currently, you may face problems if same operation is enqueued twice with different data to different streams. Some functions use the constant or texture GPU memory, and next call may update the memory before the previous one has been finished. But calling different operations asynchronously is safe because each operation has its own constant buffer. Memory copy/upload/download/set operations to the buffers you hold are also safe.

这里是小样本:

// 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;

这篇关于如何在OpenCV中使用gpu :: Stream?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆