gpt4 book ai didi

opencv - GpuMat 的空闲内存

转载 作者:太空宇宙 更新时间:2023-11-03 22:44:40 24 4
gpt4 key购买 nike

我的 CUDA 设备内存不足。我已经检测到原因 - 在我的一些成员函数中,我返回了一个 GpuMat 构建在我自己分配的数据上。这里的问题是 - 我如何释放这个内存?

class Test {
GpuMat test() {
float* dev_ptr = nullptr;
cv::Size size(8192,8192);
cudaMalloc((void**)&dev_ptr, size.width*size.height*sizeof(float));
return GpuMat(size, CV_32FC1, dev_ptr);
}
}
//main
Test t;
while(true) {
size_t free_mem, total_mem;
cudaMemGetInfo(&free_mem, &total_mem);
std::cout << free_mem << std::endl;
cv::namedWindow("test", CV_WINDOW_OPENGL | CV_WINDOW_NORMAL);
cv::imshow("test", t.test());
cv::waitKet(1);
}

您会看到每次迭代中 free_mem 的数量在减少(数量相同)。


我尝试过创建自定义分配器和 setDefaultAllocator 但它没有用。

class CustomAllocator : public cv::cuda::GpuMat::Allocator
{
float* m_ptr;
public:
CustomAllocator(float* p) : cv::cuda::GpuMat::Allocator(), m_ptr(p) {}
virtual bool allocate(cv::cuda::GpuMat* mat, int rows, int cols, size_t elemsize) override
{
return true;
}
virtual void free(cv::cuda::GpuMat* mat) override
{
cudaFree(m_ptr);
}
};
// more or less looked like this...
GpuMat test() {
float* dev_ptr = nullptr;
cv::Size size(8192,8192);
cudaMalloc((void**)&dev_ptr, size.width*size.height*sizeof(float));
GpuMat retval(size, CV_32FC1, dev_ptr);
retval.setDefaultAllocator(new CustomAllocator(dev_ptr));
return retval;
}

两者都是AllocatorGpuMat没有写得很好的文档,所以任何帮助将不胜感激。


什么看起来有用

GpuMat test() {
float* dev_ptr = nullptr;
cv::Size size(8192,8192);
cudaMalloc((void**)&dev_ptr, size.width*size.height*sizeof(float));
// do processing...
// clone data so the GpuMat manages it by itself
auto retval = GpuMat(size, CV_32FC1, dev_ptr).clone();
// free manually allocated memory
cudaFree(dev_ptr);
return retval;
}

正如我现在写下来的那样,我认为最佳方法是先分配 GpuMat,然后使用其 data//do processing...

最佳答案

您正在使用涉及用户提供的分配的 GpuMat 的特定变体。此外,t 永远不会超出您的 while 循环的范围,因此我不清楚任何隐式方法是否有效。

由于您使用 cudaMalloc 提供内存分配,我的建议是您应该使用 cudaFree 释放它。因此,简单地说,使 dev_ptr 成为类数据成员而不是立即/临时变量,并提供一个 Test::finish() 成员函数来测试此指针是否为非-NULL,如果是,则在其上运行 cudaFree()。当然,如果您想通过构造函数/析构函数进行处理,您可能会以不同的方式进行处理,并且可能有几十种可能的变化。

这是一种可能的方法,在浏览器中编码,未经测试:

class Test {
float* dev_ptr;
public:
Test() {dev_ptr = nullptr;}
void finish() { if (dev_ptr != nullptr) cudaFree(dev_ptr);}
GpuMat test() {
cv::Size size(8192,8192);
cudaMalloc((void**)&dev_ptr, size.width*size.height*sizeof(float));
return GpuMat(size, CV_32FC1, dev_ptr);
}
}
//main
Test t;
while(true) {
size_t free_mem, total_mem;
cudaMemGetInfo(&free_mem, &total_mem);
std::cout << free_mem << std::endl;
cv::namedWindow("test", CV_WINDOW_OPENGL | CV_WINDOW_NORMAL);
cv::imshow("test", t.test());
cv::waitKey(1);
t.finish();
}

或者,如果您想避免显式调用 finish(),而只是想重新分配,您可以这样做:

class Test {
float* dev_ptr;
public:
Test() {dev_ptr = nullptr;}
GpuMat test() {
cv::Size size(8192,8192);
if (dev_ptr != nullptr) cudaFree(dev_ptr);
cudaMalloc((void**)&dev_ptr, size.width*size.height*sizeof(float));
return GpuMat(size, CV_32FC1, dev_ptr);
}
}
//main
Test t;
while(true) {
size_t free_mem, total_mem;
cudaMemGetInfo(&free_mem, &total_mem);
std::cout << free_mem << std::endl;
cv::namedWindow("test", CV_WINDOW_OPENGL | CV_WINDOW_NORMAL);
cv::imshow("test", t.test());
cv::waitKey(1);
}

关于opencv - GpuMat 的空闲内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49246638/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com