基于最小可视高度的通视性算法-C++/CUDA实现

前言

对区域所有网格点进行通视计算时,计算量很大,项目后期开发肯定是要用GPU来计算的。
第一次用CUDA编程,走了太多的坑。现在流程上是完成了,结果也大致检查了下,应该没啥问题,只是代码的效率可能不足。小区域时计算速度没提升多少,区域较大时提升比较明显。打算从整体架构上来记录一下遇到的问题以及采用的应对方案,毕竟初学很多地方肯定不是最好的。
算法原理在上一篇。

架构

首先 global、device、host 得先去了解

在这里插入图片描述
在GPU中开辟的内存包括两部分,一部分是在CPU中通过cudaMemcpy申请的通视结果缓存,另一部分是GPU中计算通视申请的临时内存,包括最小通视高程矩阵和最近采样点距离矩阵,每个点计算时临时内存大于长 * 宽 * 8,因此必须实时申请、计算并释放。

内存

区域性的通视计算在GPU中完成,最重要的是要考虑GPU的内存。项目中设计的通视结果只存储了地形可视性。CPU内存不太需要考虑,因为CPU可以操作硬盘。为了节省内存,通视性结果以位为单位存储,即100*100的区域通视性结果大小为10000 * 10000 /8 字节。

最先想到的方案是是在CPU中通过 cudaMemcpy 申请好通视结果缓存区的二维矩阵(或CPU中申请一维矩阵,GPU中改为二维访问),所有点的点计算完成后从GPU中取出结果。这样导致的问题也很明显,区域太大时,需要足够大的GPU内存,我的电脑只够申请360 * 360大小的区域结果。
然后为了解决这个缺陷,我尝试的很多办法,但是都是失败了。
一:在CPU中申请二维矩阵的第一维,在GPU中实时申请第二维,通视在核函数计算通视的同时,将已计算的部分复制到CPU并释放。这个方案的目的是为了能够实时对一个点完成申请、计算与释放,这样内存大小就只需要保证同时计算点数*临时内存大小,基本解决使用GPU计算通视的限制条件。
这里失败的原因是CPU中无法对核函数内申请的内存进行访问,查了一下是因为有不同的上下文,被限制访问了。但是没查到如何解决。
二:在全局内存中申请一个点的通视结果大小(长 * 宽 / 8 + 4 字节)的内存,作为全局缓存区。在GPU中利用一个线程对缓存区进行操作,将计算好的点的通视复制到缓存区中,同时CPU中循环读取,通过互锁操作也能近似实现点通视的实时申请、计算与释放。
这里失败的原因可能是CPU中无法对正在被核函数使用的GPU内存进行访问。其实如果第一种尝试做全面一些就不用做这个尝试了。
还包括打算用常量区域来保存结果等方式,都不行,常量内存太小了。总之最后还是使用的最先想到的但是有明显缺陷的方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值