赣州新闻网

首页 / 科技

3D点云配准算法简述

2020-02-22 · 赣州新闻网 · 科技

内存映射是将磁盘上某文件的一部分或整个文件映射到应用程序地址空间内某个地址范围的一种机制。然后,应用程序可采用与访问动态内存相同的方法访问磁盘上的文件。与使用fread和fwrite等函数相比,能够加快文件的读取和写入速度。

实际上,就是将文件在磁盘上的地址映射为虚拟内存。

1.读写二进制文件

将int16二进制文件映射到内存中,跳过前1000个字c V ? + ! o ! 4节。注意是字节,不是数的个数。对于int16类型来说,相当于跳过前500个数。

m = memmapfile(\'E:\\BDSdata\\IF_0115_20M.bin\',\'Format\',\'int16\',\'offset\',1000)

可以看到,m是一种memmapfilek | %数据类型。(本质上就是个结构体)

「MATLAB数据导入与分析」MATLAB: 使用内存映射加快文件读写

此时,文件已经被映射到虚拟内存上,可以利用mU g ! # v - ~ 2 c.Data进行读取。

「MATLAB数据导入与分析」MATLAB: 使用内存映射加快文件读写

如果想要进行数据写入的话,需要将Writable值设为true,然后直接修改D E 4 = 8 X dm.Data值,即可完成对磁盘上文B P ] g 5 / m d件的修改。

m.Writable = true;
m.Data(1e8+2) = 0; % 将第1e8{ ^ ~ 9 + + 8 t `+2个数从-261修改为0
m.Data(1e8:1e8+5)
「MATLAB数据导入与分析」MATLAB: 使用内存映射加快文件读写

2.读写文本文件

%% TODO

3.} L Y f _ * . $ }读写性能实战

在之前一篇关于并行连续滤波的文章中,其中的一个重要的限制就是,文件的读取与写入不能并行,导致性能提升有限。


这里采用内存映射的读取方式,从而实现了多进程读写。滤波器函数lowpassFilter与多进程滤波函数multiProcessFilt1 y p = 9 _ A Ter都是上文中已经出现的函数。

function main()
objFiltN s ] N Ger = lowpassFilter;

% parpool(6)
tic;multiProcessFilter(objFilter,\'raw.bin\',\'multi.bin\',6);toc
% 时间已过 44.09901N W o L U H u #5 秒。7 6 X ` X y ? i V

tic;memMapMultiFilter(ob2 = CjFilter,\'raw.bin\',\'memMap.bin\'S ! i L ( B,6);toc
% 时间已过 31.000704 秒。

visdiff(\'multi.biD h [ Pn\',\'memMap.bin\',\'binD N L { v tary\');
% 这些文件相同
end

function memMapMultk 8iFilter(objFilter,rawFile,3 G i ~ s F a R SprocessFile,M)
% 复制一份原文件,在新文件的基础上写入得到滤波后的文件
copyfile(rawFile,processFile,\'f\');
% 将原文件映射到虚拟内存
raw = memmapfileQ J d W :(rawFile,\'Format\',\'int8\');
% 将新文件映射到虚拟内存
filtered = memmapfile(p& 9 )rocessFile,\'Format\',\'int8\',\'Writable3 ; p L p \',true);
overlap = lengthH Z _(objFilter.States);

len = length(raw.Data);
workload = 2I p . y 8e7;
numOfWork = round(len/M/wo* U 3 H c ) F yrkload);
idx = round(linspace(! + V Z x v1,len,numOfWork*M+1));
idx_lap = idx + ov| U q U =erlap;
idx_lap(end) = lenf m p;
spmd(M)
for ii = 1:numOfWork
jj = (labindex-1)*nu. K _ c o n Y FmOfWork + ii;
if jj == 1
fdU m H 4 U D #ata = filh ( + _ Yter(objFi; l j Flter,raw.Data(1:idx_lap(2)));
filtered.Data(1:idx/ ` b 6 V 9 S b %_lap(2)) = int8(fdata);
else
fdata = filter(objFilter,raw.Data(idx(jj):idx_lap(jj+1)));
filtered.Data(idx_lap(jj):idx_lap(jj+1)) = int8(fdata(overlap+1:end));
end; j y K D
end
end
end

可H m 0 p D X : (以看到,使用68阶FI_ ^ y = Y cRZ g . K ` M滤波器对1.2G的int8文件进行滤波X W w ( s ^,使用fread/fwrite^ 5 2 _ 7 | W函数进行读写$ 5 8 # . l L *,6进程滤波需要约44秒。而使用内存映射memmapfile函数,6进程滤波仅需31秒, 3速度提高了大约30%。

总结

  1. 使用内存映射比标准I/O函数拥有更快的访问速, # g y E d j度,使用操作系统虚拟内存~ . 4 4功能读取和写入数据,而不必分配数据缓冲区。
  2. 利用内存映射,可以像访问数组一样( 6 f M f i 1访问W r 6 y Q ? A Y文件,直接使用MATLAB的索引操作,更加简洁。
  3. 利用内存映射,可以在不同的函数之间共享数据。(类似于共享内存)
  4. 内存映射的释放是一个坑点。官方文档上面声称,退出创建% W .内存映射的函数时,会自动清除掉内存映射,实测某些情况下不会,可能= O Q导致无法对文件进行操作,此时只能重启MA+ } v U O l KTLAB。为了避免这点,建议在函数结尾用clear命令清除内存v P 7 I G映射。

有用就收藏K w C 5 y 7 Y |点赞关注哦。持续/ q Z关注有N r |福利

文章结尾类型加快导致功能3D全南算法