OpenCV 4.12.0
开源计算机视觉
加载中...
搜索中...
无匹配项
cv::cuda::BufferPool 类参考

用于 CUDA 流的 BufferPool更多...

#include <opencv2/core/cuda.hpp>

cv::cuda::BufferPool 协作图

公共成员函数

 BufferPool (Stream &stream)
 获取给定流的 BufferPool
 
Ptr< GpuMat::AllocatorgetAllocator () const
 返回与流关联的分配器。
 
GpuMat getBuffer (int rows, int cols, int type)
 分配指定大小和类型的新 GpuMat
 
GpuMat getBuffer (Size size, int type)
 分配指定大小和类型的新 GpuMat
 

详细描述

用于 CUDA 流的 BufferPool

BufferPool 利用 Stream 的分配器为 GpuMat 创建新缓冲区。它只有在使用 setBufferPoolUsage 启用时才有用。

void setBufferPoolUsage(bool on)
BufferPool 管理(必须在 Stream 创建之前调用)
注意
setBufferPoolUsage 必须在任何 Stream 声明之前调用。

用户可以为 Stream 指定自定义分配器,并可以实现他们自己的利用相同底层 GPU 内存管理的基于流的函数。

如果未指定自定义分配器,BufferPool 默认使用 StackAllocator。StackAllocator 预先分配一块 GPU 设备内存,当 GpuMat 稍后声明时,它会获得预分配的内存。这种策略减少了对内存分配 API(如 cudaMalloc 或 cudaMallocPitch)的调用次数。

下面是一个利用 BufferPool 与 StackAllocator 的示例:

#include <opencv2/opencv.hpp>
using namespace cv;
using namespace cv::cuda
int main()
{
setBufferPoolUsage(true); // 告诉 OpenCV 我们将使用 BufferPool
setBufferPoolConfig(getDevice(), 1024 * 1024 * 64, 2); // 分配 64 MB,2 个栈(默认是 10 MB,5 个栈)
Stream stream1, stream2; // 每个流使用 1 个栈
BufferPool pool1(stream1), pool2(stream2);
GpuMat d_src1 = pool1.getBuffer(4096, 4096, CV_8UC1); // 16MB
GpuMat d_dst1 = pool1.getBuffer(4096, 4096, CV_8UC3); // 48MB,pool1 已满
GpuMat d_src2 = pool2.getBuffer(1024, 1024, CV_8UC1); // 1MB
GpuMat d_dst2 = pool2.getBuffer(1024, 1024, CV_8UC3); // 3MB
cvtColor(d_src1, d_dst1, cv::COLOR_GRAY2BGR, 0, stream1);
cvtColor(d_src2, d_dst2, cv::COLOR_GRAY2BGR, 0, stream2);
}
用于 CUDA 流的 BufferPool。
定义 cuda.hpp:748
带引用计数的 GPU 内存的基本存储类。
定义 cuda.hpp:106
此类封装了一个异步调用队列。
定义 cuda.hpp:917
#define CV_8UC1
定义 interface.h:88
CV_8UC3
#define CV_8UC3
int getDevice()
返回由 cuda::setDevice 设置或默认初始化的当前设备索引。
void setBufferPoolConfig(int deviceId, size_t stackSize, int stackCount)
void cvtColor(InputArray src, OutputArray dst, int code, int dcn=0, Stream &stream=Stream::Null())
将图像从一个颜色空间转换为另一个颜色空间。
@ COLOR_GRAY2BGR
定义 imgproc.hpp:559
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
定义 cuda.hpp:65
定义 core.hpp:107

如果在上面的示例中,我们在 pool1 上分配另一个 GpuMat,它将由 DefaultAllocator 执行,因为 pool1 的栈已满。

GpuMat d_add1 = pool1.getBuffer(1024, 1024, CV_8UC1); // pool1 的栈已满,内存由 DefaultAllocator 分配

如果在上面的示例中声明了第三个流,那么在该流中用 getBuffer 进行分配也将由 DefaultAllocator 执行,因为我们已用完栈。

Stream stream3; // 只分配了 2 个栈,我们已用完栈
BufferPool pool3(stream3);
GpuMat d_src3 = pool3.getBuffer(1024, 1024, CV_8UC1); // 内存由 DefaultAllocator 分配
警告
当使用 StackAllocator 时,释放顺序很重要。

就像栈一样,释放必须以 LIFO(后进先出)顺序完成。下面是一个违反 LIFO 规则的错误用法示例。如果 OpenCV 以调试模式编译,此示例代码将发出 CV_Assert 错误。

int main()
{
setBufferPoolUsage(true); // 告诉 OpenCV 我们将使用 BufferPool
Stream stream; // 为此流分配了默认大小(10 MB)的栈
BufferPool pool(stream);
GpuMat mat1 = pool.getBuffer(1024, 1024, CV_8UC1); // 分配 mat1 (1MB)
GpuMat mat2 = pool.getBuffer(1024, 1024, CV_8UC1); // 分配 mat2 (1MB)
mat1.release(); // 错误用法:mat2 必须在 mat1 之前释放
}
void release()
减少引用计数,当引用计数达到 0 时释放数据

由于 C++ 局部变量以与构造相反的顺序销毁,下面的代码示例满足 LIFO 规则。局部 GpuMat 被释放,相应的内存会自动返回到池中以供后续使用。

int main()
{
setBufferPoolUsage(true); // 告诉 OpenCV 我们将使用 BufferPool
setBufferPoolConfig(getDevice(), 1024 * 1024 * 64, 2); // 分配 64 MB,2 个栈(默认是 10 MB,5 个栈)
Stream stream1, stream2; // 每个流使用 1 个栈
BufferPool pool1(stream1), pool2(stream2);
for (int i = 0; i < 10; i++)
{
GpuMat d_src1 = pool1.getBuffer(4096, 4096, CV_8UC1); // 16MB
GpuMat d_dst1 = pool1.getBuffer(4096, 4096, CV_8UC3); // 48MB,pool1 已满
GpuMat d_src2 = pool2.getBuffer(1024, 1024, CV_8UC1); // 1MB
GpuMat d_dst2 = pool2.getBuffer(1024, 1024, CV_8UC3); // 3MB
d_src1.setTo(Scalar(i), stream1);
d_src2.setTo(Scalar(i), stream2);
cvtColor(d_src1, d_dst1, cv::COLOR_GRAY2BGR, 0, stream1);
cvtColor(d_src2, d_dst2, cv::COLOR_GRAY2BGR, 0, stream2);
// 局部变量的销毁顺序是
// d_dst2 => d_src2 => d_dst1 => d_src1
// 满足 LIFO 规则,此代码运行无误
}
}
GpuMat & setTo(Scalar s)
将某些 GpuMat 元素设置为 s (阻塞调用)
Scalar_< double > Scalar
定义 types.hpp:709

构造函数 & 析构函数文档

◆ BufferPool()

cv::cuda::BufferPool::BufferPool ( Stream & )
显式
Python
cv.cuda.BufferPool() -> <cuda_BufferPool object>

获取给定流的 BufferPool

成员函数文档

◆ getAllocator()

Ptr< GpuMat::Allocator > cv::cuda::BufferPool::getAllocator ( ) const
inline
Python
cv.cuda.BufferPool.getAllocator() -> retval

返回与流关联的分配器。

◆ getBuffer() [1/2]

GpuMat cv::cuda::BufferPool::getBuffer ( int rows,
int cols,
int type )
Python
cv.cuda.BufferPool.getBuffer(rows, cols, type) -> retval
cv.cuda.BufferPool.getBuffer(size, type) -> retval

分配指定大小和类型的新 GpuMat

◆ getBuffer() [2/2]

GpuMat cv::cuda::BufferPool::getBuffer ( Size size,
int type )
inline
Python
cv.cuda.BufferPool.getBuffer(rows, cols, type) -> retval
cv.cuda.BufferPool.getBuffer(size, type) -> retval

分配指定大小和类型的新 GpuMat

此函数的调用图如下

此类的文档是从以下文件生成的