CUDA编程之GPU图像数据结构的设计

这篇具有很好参考价值的文章主要介绍了CUDA编程之GPU图像数据结构的设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第1章 GPU图像数据结构

参考OpenCV中Mat和GpuMat的设计,对当前Image类设计了GPU版本,即GPUImage。

1.1. GPU图像头

设计图像头。

struct GPUImageHeader
{
   
	int32_t nWidth = 0;    //宽度
	int32_t nHeight = 0;	//高度
	int16_t nChannel = 0;  //通道数
	int32_t nRefCount = 0;  //引用计数
	void* pImage = nullptr;
};

其中指针指向的是GPU上的地址。引用计数用来实现浅拷贝以及显存的自动释放管理。不像OpenCV和Nppi,分通道和深度的做法。GPUImage的nChannel可以理解为通道*深度。

1.2. GPU图像数据结构接口

GPUImage用来管理CudaMalloc申请的显存,在GBox设备上,使用CudaMallocManaged来申请的GPU和CPU共用的地址。绑定功能暂不实现。

class BASE_EXPORT GPUImage
{
   
public:
	GPUImage();
	GPUImage(int nW, int nH, int nD); //create
	~GPUImage();

	GPUImage(const GPUImage& m);
	GPUImage& operator=(const GPUImage& m);

	void Create(int nW, int nH, int nC);  //使用默认的内存布局
	void Release();

	//增加一个和常规图像的互
	GPUImage(Image& m);
	bool ToImage(Image& m);
	bool FromImage(Image& m);

	//Get
	void* Ptr();
	int Width();
	int Height();
	int Depth();
	Rect Rect();

private:
	GPUImageHeader* m_pHeader = nullptr;
};

1.2.1. 图像创建操作

图像创建操作:

void GPUImage::Create(int nW, int nH, int nC)
{
   
	if (DebugCmd)
		std::cout << "void Matrix::Create(int nW, int nH, int nC)" << std::endl;

	//释放当前
	Release();

	m_pHeader = new GPUImageHeader();
	m_pHeader->nWidth = nW;
	m_pHeader->nHeight = nH;
	m_pHeader->nChannel = nC;

	size_t memSize = m_pHeader->nWidth * m_pHeader->nHeight * m_pHeader->nChannel + 31;
	auto ret = cudaMalloc((void**)&(m_pHeader->pImage), memSize);
	//如果ret不对,要抛异常
	if (ret != cudaSuccess)
		throw std::exception("GPUImage::FromImage(Image& m) error");

	META_ATOMIC_ADD(&m_pHeader->nRefCount, 1);
	if (DebugCmd)
		std::cout << "m_Image.nRefCount:" << m_pHeader->nRefCount << std::endl;
}

采用cudamalloc申请图像空间。

1.2.2. 图像释放操作

图像释放操作:

void GPUImage::Release()
{
   
	if (DebugCmd)
		std::cout << "Release()" << std::endl;

	if (m_pHeader)
	{
   
		assert(m_pHeader->nRefCount > 0);
		if (META_ATOMIC_ADD(&m_pHeader->nRefCount, -1) == 1)
		{
   
			if (m_pHeader->pImage)
			{
   
				auto ret = cudaFree(m_pHeader->pImage);
				//如果ret不对,要抛异常
				if (ret != cudaSuccess)
					throw std::exception("GPUImage::FromImage(Image& m) error");
			}
			m_pHeader->pImage = nullptr;

			delete m_pHeader;
			m_pHeader = nullptr;
			if (DebugCmd)
				std::cout << "Release::m_pHeader:delete" << std::endl;
		}
		else
		{
   
			if (DebugCmd)
				std::cout << "Release::m_Image.nRefCount:" << m_pHeader->nRefCount << std::endl;
		}
	}
	else
	{
   
		if (DebugCmd)
			std::cout << "m_pHeader == nullptr" << std::endl;
	}
}

释放时要判断引用计数,只有降为0,才进行显存的释放。

1.2.3. 图像拷贝构造和赋值构造

图像拷贝构造:

GPUImage::GPUImage(const GPUImage& m)
{
   
	if (DebugCmd)
		std::cout << "Matrix(const Matrix& m)" << std::endl;
	if (m.m_pHeader)
	{
   
		META_ATOMIC_ADD(&m.m_pHeader->nRefCount, 1);
		m_pHeader = m.m_pHeader;
		if (DebugCmd)
			std::cout << "m_Image.nRefCount:" << m_pHeader->nRefCount << std::endl;
	}
	else
	{
   
		m_pHeader = nullptr;
		if (DebugCmd)
			std::cout << "m_Image.nRefCount:0,m_pHeader == nullptr" << std::endl;
	}
}

拷贝时,并不申请显存,而是将引用计算加1。
赋值构造:

GPUImage& GPUImage::operator=(const GPUImage& m)
{
   
	if (DebugCmd)
		std::cout << "Matrix& operator=(const Matrix& m)" << std::endl;
	if (this->m_pHeader != m.m_pHeader)
	{
   
		if (m.m_pHeader)
		{
   
			META_ATOMIC_ADD(&m.m_pHeader->nRefCount, 1);
			Release();  //释放当前
			m_pHeader = m.m_pHeader;
			if (DebugCmd)
				std::cout << "m_Image.nRefCount:" << m_pHeader->nRefCount << std::endl;
		}
		else
		{
   
			m_pHeader = nullptr;
			if (DebugCmd)
				std::cout << "m_Image.nRefCount:0,m_pHeader == nullptr" << std::endl;
		}
	}
	else
	{
   
		if (DebugCmd)
			std::cout << "this->m_pHeader == m.m_pHeader" << std::endl;
	}

	return *this;
}

赋值构造时,要释放被赋值图像,,然后把赋值图像引用计数加1。

1.3. GPU图像数据结构引用计数测试

将上述DebugCmd打开,测试如下代码:文章来源地址https://www.toymoban.com/news/detail-667454.html

void test1(MetaCore::GPUImage imA)
{
   
    std::cout << "期望引用计数会减1" << std::endl;
    return;
}
void test2(MetaCore::GPUImage& imB)
{
   
    std::cout << "期望不发生任何事情" << std::endl;
    return;
}
MetaCore::GPUImage test3()

到了这里,关于CUDA编程之GPU图像数据结构的设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【数据结构与算法】设计循环队列

    【数据结构与算法】设计循环队列

      🧑‍🎓 个人主页:简 料   🏆 所属专栏:C++   🏆 个人社区:越努力越幸运社区   🏆 简       介: 简料简料,简单有料~在校大学生一枚,专注C/C++/GO的干货分享,立志成为您的好帮手 ~ C/C++学习路线 (点击解锁) ❤️ C语言阶段(已结束) ❤️ 数据结构与算法(ing) ❤

    2024年01月17日
    浏览(11)
  • 【编程实践】JVM内存管理的核心数据结构和算法思想&代码示例说明
  • 数据结构算法设计——哈希表(散列表)

    数据结构算法设计——哈希表(散列表)

            哈希表 又叫 散列表 ,他们两个是同一个东西,本文全文采用“散列表”的叫法。散列表的本质其实就是一个 数组 ,他的作用就像使用数组时一样,输入下标可以得到对应元素,散列表可以实现 输入一个的时候得到这个的地址信息 。 下面是百科给出

    2024年02月03日
    浏览(14)
  • 【数据结构与算法】之8道顺序表与链表典型编程题心决!

    【数据结构与算法】之8道顺序表与链表典型编程题心决!

                                                                                    个人主页:秋风起,再归来~                                                                                             数据结构与算

    2024年04月14日
    浏览(39)
  • 软件设计师:05-数据结构与算法

    软件设计师:05-数据结构与算法

    本章难度在软件设计师中最高,推荐最后一章进行学习 章节 章节 01 - 计算机组成原理与体系结构 07 - 法律法规与标准化与多媒体基础 02 - 操作系统基本原理 08 - 设计模式 03 - 数据库系统 09 - 软件工程 04 - 计算机网络 10 - 面向对象 05 - 数据结构与算法 11 - 结构化开发与UML 06

    2024年02月03日
    浏览(8)
  • 《数据结构与算法分析》课程设计——迷宫问题

    《数据结构与算法分析》课程设计——迷宫问题

    中国矿业大学信控学院   补一下我之前在博客园发布的内容  懒得调了, 想复制完整代码直接复制最下面的 ,想复制分布代码去看我博客园链接吧 《数据结构与算法分析》课程设计——迷宫问题 - 刷子zz - 博客园 一、  问题描述 问题中迷宫可用方阵[m,n]表示,0表示能通过

    2024年02月10日
    浏览(8)
  • 链表综合算法设计(c++数据结构)

      一、设计内容 已知简单的人事信息系统中职工记录包含职工编号(no)、职工姓名(name)、部门名称(depname)、职称(title)和工资数(salary)等信息(可以增加其他信息),设计并完成一个简单的人事信息管理系统,要求完成但不限于以下功能: (1)    增加一个职工信息

    2024年02月02日
    浏览(13)
  • 【C程序设计】——程序=算法+数据结构

    【C程序设计】——程序=算法+数据结构

    目录 🍊🍊一、什么是算法? 🍊🍊二、简单的算法举例 🍊🍊三、算法的特性 🍊🍊四、怎样表示一个算法  一个程序主要包括以下两方面的信息: (1)对数据的描述。在程序中要指定用到哪些数据,以及这些数据的类型和数据的组织形式。这就是 数据结构 (data struct

    2024年02月06日
    浏览(13)
  • 【软件设计师06】数据结构与算法基础

    【软件设计师06】数据结构与算法基础

    考点:数组与矩阵、 线性表 、广义表、 树与二叉树 、图、 排序与查找 、 算法基础与常见的算法 数组类型 存储地址计算 一维度数组a[n] a[i]的存储地址为a+i*len 二维数组a[m][n] a[i][j]的存储地址;按行存储:a+(i*n+j)*len;按列存储:a+(j*m+i)*len 采用上三角或者下三角的形式存储

    2023年04月11日
    浏览(5)
  • 数据结构与算法课程设计---最小生成树的应用

    数据结构与算法课程设计---最小生成树的应用

    1.问题 假定有这么一个问题,有11个城市,城市之间有一些天然气管道,铺设天然气管道需要花费不同的金额,现在要你选择其中一些天然气管道,使得所有城市可以互相联通且花费最小。 2.分析 我们把这个问题抽象为一张图,每个城市是一个顶点,城市与城市之间的管道是

    2024年02月08日
    浏览(16)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包