OpenCV  4.10.0
开源计算机视觉库
加载中...
搜索中...
无匹配项
公共成员函数 | 所有成员列表
cv::cuda::BufferPool 类参考

BufferPool 用于 CUDA 流。 更多...

#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
 

详细描述

BufferPool 用于 CUDA 流。

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:739
具有引用计数的 GPU 内存的基本存储类。
定义 cuda.hpp:106
此类封装了异步调用的队列。
定义 cuda.hpp:908
#define CV_8UC1
定义 interface.h:88
#define CV_8UC3
定义 interface.h:90
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:557
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
定义 cuda.hpp:65
"黑盒" 表示与磁盘上的文件关联的文件存储。
定义 core.hpp:102

如果我们在上面的示例中在 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(); // 错误使用:必须在 mat1 之前释放 mat2
}
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:702

构造函数和析构函数文档

◆ BufferPool()

cv::cuda::BufferPool::BufferPool ( Stream stream)
explicit
Python
cv.cuda.BufferPool(stream) -> <cuda_BufferPool 对象>

获取给定流的 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 ( 大小  大小,
int  type 
)
inline
Python
cv.cuda.BufferPool.getBuffer(rows, cols, type) -> retval
cv.cuda.BufferPool.getBuffer(size, type) -> retval

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

以下是此函数的调用图

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