第一part 点云数据的解析成图
需要自行配置jsoncpp、OpenCV运行环境
1. 点云数据的解析成图模块设计
测试环境
i5-9400f 16g (测试情况和实机性能有关)
线程解析(以法如的三维扫描仪生成的fls文件为基础)
1.多线程解析数据效率
项目 | c++耗时 |
---|---|
解析一个fls | 20秒 |
解析3个fls | 25秒 |
解析6个fls | 37秒 |
解析7个fls | 46秒 |
解析9个fls | 57秒 |
解析15个fls | 96秒 |
解析20个fls | 134秒 |
解析40个fls | 266秒 |
解析-加载里程-解析空间(单文件) | 240秒 |
解析-加载里程-解析空间-成图(单文件) | 291秒 |
解析-加载里程-解析空间-成图(两个文件) | 291秒 |
解析-加载里程-解析空间-成图(5个文件) | 667秒 |
解析-加载里程-解析空间-成图(6个文件) | 727秒 |
2.单线程和解析
项目 | c++耗时 |
---|---|
解析一个fls | 20秒 |
解析6个fls | 104秒 |
解析7个fls | 127秒 |
解析15个fls | 260秒 |
解析20个fls | 376秒 |
解析40个fls | 729秒 |
3.新环境重测 (i7-9700+16g+GTX1660Ti )
单线程解析 此过程只是解析fls,并不包含成图
项目 | c++耗时 | 2021年11月23日下午3点重测(占用内存) |
---|---|---|
解析一个fls | 10秒 | c++:16秒(243MB) |
解析两个fls | 31秒 | c++:33秒(310MB) |
解析三个fls | 47秒 | c++:49秒(288,6MB) |
解析四个fls | 64秒 | c++:65秒(278MB) |
解析五个fls | 80秒 | c++:84秒(311.4MB) |
解析六个fls | 95秒 | – |
2021年11月23日下午3点结果:
每个fls解析的平均时间:c++===》16.42秒
单线程成图
扫描仪生成一个FLS文件的时间是约30S
此测试过程包括解析fls—里程解析----空间解析处理----成图
项目 | c++第一版耗时(精度、占用内存) | c++第二版优化耗时(精度、占用内存) |
---|---|---|
一个fls成图 | 150秒(2mm、4G) | 26秒(2mm、3.9G)\ 26秒(5mm、3.8G) |
两个fls成图 | 303秒(2mm、4G) | 53(2mm、4.4G)\ 53秒(5mm、4.4G) |
三个fls成图 | 453秒(2mm、5G) | 79秒(2mm、5.0G) \ 78秒(5mm、4.9G) |
四个fls成图 | 602秒(2mm、6G) | 105秒(2mm、5.1G)\ 103秒(5mm、5.4G) |
五个fls成图 | 757秒(2mm、6G) | 131秒(2mm、6.1G)\ 128秒(5mm、6G) |
六个fls成图 | 911秒(2mm、7G) | 157秒(2mm、6.6G)\ 154秒(5mm、6.6G) |
第一版是在i5处理器上进行的,之后我做了调整,就在i7处理器上运行了
第二版的测试情况
- 2mm(成图的精度,不懂的自行查阅OpenCV)成图内存占用情况
- 2mm成图cpu占用情况
- 5mm成图内存占用情况
- 5mm成图cpu占用情况
- c++第一版的运行过程中出现132秒长时间的占用4G内存的情况
- c++第二版的运行过程以梯度的形式占用内存,也就是上表中占用内存的记录只用1秒,之后又会逐渐减低。减少在磁盘的读写频率
多线程解析
多线程解析fls(当前环境同时开了10个线程解析fls效率出现严重低下,所以没有10个以上的多线程解析数据分析)
项目 | c++耗时(消耗内存) |
---|---|
解析两个fls | 10秒(453M) |
解析三个fls | 22秒(743M) |
解析四个fls | 25秒(911M) |
解析五个fls | 29秒(1G) |
解析六个fls | 32秒(1G) |
解析七个fls | 37秒(2G) |
解析八个fls | 39秒(3G) |
解析九个fls | 43秒(3G) |
多线程成图(成图过程和单线程一样)
项目 | c++耗时(消耗内存) | c++第二版优化耗时(精度、占用内存) |
---|---|---|
两个fls成图 | 216秒(5G) | 37.4秒(2mm、7.7G)\ 35秒(5mm、7.8G) |
三个fls成图 | 250秒(9G) | 45秒(2mm、11G)\ 46.1秒(5mm、11.6G) |
四个fls成图 | 320秒(13G) | 65秒(2mm、15.2G)\ 61秒(5mm、15.3G) |
五个fls成图 | 380秒(15G) | –(2mm、19G)内存过载,本机暂时无法完成测试 |
六个fls成图 | 470秒(18G) | – |
测试情况
- 2mm成图多线程解析2个占用情况
- 2mm成图多线程解析3个占用情况
- 2mm成图多线程解析4个占用情况
- 2mm成图多线程解析5个占用情况
- 5mm成图多线程解析2个占用情况
- 5mm成图多线程解析3个占用情况
4.图片质量
5.设计思路
- 数据存储
* 问题:数据的处理量达到了上千万级别,在程序运行一段时间之后,再次进行数据读入操作,会出现内存溢出的异常。
* 原因:对较大的数据量的数组进行较为频繁的读入操作(数组大小为500M以上),在循环中创建了多个对象。
* 解决:c++版本采用容器代替数组来承载数据,安全、防止爆栈
* 对比起数组,vector是安全的(假设一个arraylist里现在只有给产品可以消费,但是有两个消费者线程请求消费,数组就会出现:可能出现一个产品被同时消费的问题,这与实际不相符。至于vector容器不会出现数组的问题,因为内部机制是同一时刻只能有一个线程对这个变量操作)
* 防止爆栈,用于存储对象的数组存放在栈中,一般机器的栈大小是1~2M,vector存在堆中,对象是存在堆中,windows的堆空间,约2G。
1. 指针大小:内存是由字节组成的,每个字节都有一个编号。指针变量主要是存放相同数据类型的变量的首地址。这里的这个地址其实就是内存的某个字节的编号。而这个编号的确定是与地址总线有关。如果地址总线是32位,则它的寻址范围是02^32(04G)。那么为一个字节的编址就会由32个0或者1组成。例如第一个字节的编址是32个0,最后一个的编址是32个1。一个字节有8位,32位则需要4个字节。
2. 对象大小:组成(对象头8字节,指针4字节,数据存储区域(不定,int是4字节,char是2字节),对其补充(补充到整个大小为8字节的倍数)),存储int类型对象是16+x,存储char对象是14+x
以上储存int对象的大小是指针的4倍以上。
使用openCV生成当通道图,8byte(成对象的图像数据需要byte类型),byte对应的c++版本是unsinged int
1MB = 1048576字节 = 32768个int对象(c++)
2MB = 2097152字节 = 65536个int对象(c++)
2G = 2048MB = 2147483648个字节 = 67108864个int对象
单个fls解析出来的数据量是19492421个对象,无论是1M还是2M的栈空间都不够存放
存放在堆空间的情况下,可解析的fls内容量可以是现在fls数据量的3倍
3. 实际上c#版本,正常来说,已经出现爆栈的情况 得益于c#对内部分段计算优化,在C#中使用数组,可以获取在内存上连续的相同类型的一组变量,在连续访问时可以满足CPU访问寄存器的时间局部性和空间局部性,大大提高了对大量数据的访问效率
当然你可以手动的去给栈分配更大的空间来防止这样的情况。
6.运行过程
7.源码地址 大家参考和共同学习 谢谢
https://gitee.com/lihenggeek/deer-project.git