matlab读int16读文件_MATLAB: 使用内存映射加快文件读写
內(nèi)存映射是將磁盤上某文件的一部分或整個(gè)文件映射到應(yīng)用程序地址空間內(nèi)某個(gè)地址范圍的一種機(jī)制。然后,應(yīng)用程序可采用與訪問(wèn)動(dòng)態(tài)內(nèi)存相同的方法訪問(wèn)磁盤上的文件。與使用fread和fwrite等函數(shù)相比,能夠加快文件的讀取和寫入速度。
實(shí)際上,就是將文件在磁盤上的地址映射為虛擬內(nèi)存。
1.讀寫二進(jìn)制文件
將int16二進(jìn)制文件映射到內(nèi)存中,跳過(guò)前1000個(gè)字節(jié)。注意是字節(jié),不是數(shù)的個(gè)數(shù)。對(duì)于int16類型來(lái)說(shuō),相當(dāng)于跳過(guò)前500個(gè)數(shù)。
m = memmapfile('E:\BDSdata\IF_0115_20M.bin','Format','int16','offset',1000)
可以看到,m是一種memmapfile數(shù)據(jù)類型。(本質(zhì)上就是個(gè)結(jié)構(gòu)體)
此時(shí),文件已經(jīng)被映射到虛擬內(nèi)存上,可以利用m.Data進(jìn)行讀取。
如果想要進(jìn)行數(shù)據(jù)寫入的話,需要將Writable值設(shè)為true,然后直接修改m.Data值,即可完成對(duì)磁盤上文件的修改。
m.Writable = true;
m.Data(1e8+2) = 0; % 將第1e8+2個(gè)數(shù)從-261修改為0
m.Data(1e8:1e8+5)
2.讀寫文本文件
%% TODO
3.讀寫性能實(shí)戰(zhàn)
在之前一篇關(guān)于并行連續(xù)濾波的文章中,其中的一個(gè)重要的限制就是,文件的讀取與寫入不能并行,導(dǎo)致性能提升有限。易夕:MATLB并行計(jì)算之多進(jìn)程連續(xù)濾波?zhuanlan.zhihu.com
這里采用內(nèi)存映射的讀取方式,從而實(shí)現(xiàn)了多進(jìn)程讀寫。濾波器函數(shù)lowpassFilter與多進(jìn)程濾波函數(shù)multiProcessFilter都是上文中已經(jīng)出現(xiàn)的函數(shù)。
functionmain()objFilter = lowpassFilter;
% parpool(6)
tic;multiProcessFilter(objFilter,'raw.bin','multi.bin',6);toc
% 時(shí)間已過(guò) 44.099015 秒。
tic;memMapMultiFilter(objFilter,'raw.bin','memMap.bin',6);toc
% 時(shí)間已過(guò) 31.000704 秒。
visdiff('multi.bin','memMap.bin','binary');
% 這些文件相同
end
functionmemMapMultiFilter(objFilter,rawFile,processFile,M)% 復(fù)制一份原文件,在新文件的基礎(chǔ)上寫入得到濾波后的文件
copyfile(rawFile,processFile,'f');
% 將原文件映射到虛擬內(nèi)存
raw = memmapfile(rawFile,'Format','int8');
% 將新文件映射到虛擬內(nèi)存
filtered = memmapfile(processFile,'Format','int8','Writable',true);
overlap = length(objFilter.States);
len = length(raw.Data);
workload = 2e7;
numOfWork = round(len/M/workload);
idx = round(linspace(1,len,numOfWork*M+1));
idx_lap = idx + overlap;
idx_lap(end) = len;
spmd(M)
for ii = 1:numOfWork
jj = (labindex-1)*numOfWork + ii;
if jj == 1
fdata = filter(objFilter,raw.Data(1:idx_lap(2)));
filtered.Data(1:idx_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
end
end
end
可以看到,使用68階FIR濾波器對(duì)1.2G的int8文件進(jìn)行濾波,使用fread/fwrite函數(shù)進(jìn)行讀寫,6進(jìn)程濾波需要約44秒。而使用內(nèi)存映射memmapfile函數(shù),6進(jìn)程濾波僅需31秒,速度提高了大約30%。
總結(jié)使用內(nèi)存映射比標(biāo)準(zhǔn)I/O函數(shù)擁有更快的訪問(wèn)速度,使用操作系統(tǒng)虛擬內(nèi)存功能讀取和寫入數(shù)據(jù),而不必分配數(shù)據(jù)緩沖區(qū)。
利用內(nèi)存映射,可以像訪問(wèn)數(shù)組一樣訪問(wèn)文件,直接使用MATLAB的索引操作,更加簡(jiǎn)潔。
利用內(nèi)存映射,可以在不同的函數(shù)之間共享數(shù)據(jù)。(類似于共享內(nèi)存)
內(nèi)存映射的釋放是一個(gè)坑點(diǎn)。官方文檔上面聲稱,退出創(chuàng)建內(nèi)存映射的函數(shù)時(shí),會(huì)自動(dòng)清除掉內(nèi)存映射,實(shí)測(cè)某些情況下不會(huì),可能導(dǎo)致無(wú)法對(duì)文件進(jìn)行操作,此時(shí)只能重啟MATLAB。為了避免這點(diǎn),建議在函數(shù)結(jié)尾用clear命令清除內(nèi)存映射。易夕:MATLAB Tricks 專欄目錄?zhuanlan.zhihu.com
總結(jié)
以上是生活随笔為你收集整理的matlab读int16读文件_MATLAB: 使用内存映射加快文件读写的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: js 数组遍历符合条件跳出循环体_Jav
- 下一篇: 机器人焊枪动作与编程实验_机器人编程实验