Chr*_*ris 4 performance matlab binaryfiles
我有一些相当大的 int16 格式的数据文件(256 个通道,大约 75-1 亿个样本 = 每个文件约 40-50 GB 左右)。它以平面二进制格式编写,因此结构类似于:CH1S1,CH2S1,CH3S1 ... CH256S1,CH1S2,CH2S2,...
我需要分别读取每个通道,进行过滤和偏移校正,然后保存。我当前的瓶颈是加载每个通道,这大约需要 7-8 分钟……扩大到 256 倍,光是加载数据就需要近 30 个小时!我正在尝试智能地使用 fread,在读取每个通道时跳过字节;我在所有 256 个通道上循环使用以下代码来执行此操作:
offset = i - 1;
fseek(fid,offset*2,'bof');
dat = fread(fid,[1,nSampsTotal],'*int16',(nChan-1)*2);
Run Code Online (Sandbox Code Playgroud)
仔细阅读,这通常是加载大型二进制文件部分的最快方法,但文件是否太大而无法更快地完成此操作?
我没有加载那么多数据...我正在使用的测试文件是 37GB,对于 256 个通道之一,我只为整个跟踪加载 149MB...也许是 fread 的“跳过”功能是次优的吗?
系统详细信息:MATLAB 2017a、Windows 7、64 位、32GB RAM
@CrisLuengo 的想法要快得多:本质上,对数据进行分块,加载每个块,然后将其拆分为单独的通道文件以节省 RAM。
下面是一些加载部分的代码,速度很快,不到 1 分钟:
% fake raw data
disp('building... ');
nChan = 256;
nSampsTotal = 10e6;
tic; DATA = rand(nChan,nSampsTotal); toc;
fid = fopen('rawData.dat','w');
disp('writing flat binary file... ');
tic; fwrite(fid,DATA(:),'int16'); toc;
fclose(fid);
% compute the number of samples and chunks
chunkSize = 1e6;
nChunksTotal = ceil(nSampsTotal/chunkSize);
%% load by chunks
t1 = tic;
fid = fopen('rawData.dat','r');
dat = zeros(nChan,chunkSize,'int16');
chunkCnt = 1;
while 1
tic
if chunkCnt <= nChunksTotal
% load the data
fprintf('Chunk %02d/%02d: loading... ',chunkCnt,nChunksTotal);
dat = fread(fid,[nChan,chunkSize],'*int16');
else
break;
end
toc;
chunkCnt = chunkCnt + 1;
end
t = toc(t1); fprintf('Total time: %4.2f secs.\n\n\n',t);
% Total time: 55.07 secs.
fclose(fid);
Run Code Online (Sandbox Code Playgroud)
另一方面,通过跳过文件按通道加载大约需要 20 倍的时间,略多于 20 分钟:
%% load by channels (slow)
t1 = tic;
fid = fopen('rawData.dat','r');
dat = zeros(1,nSampsTotal);
for i = 1:nChan
tic;
fprintf('Channel %03d/%03d: loading... ');
offset = i-1;
fseek(fid,offset*2,'bof');
dat = fread(fid,[1,nSampsTotal],'*int16',(nChan-1)*2);
toc;
end
t = toc(t1); fprintf('Total time: %4.2f secs.\n\n\n',t);
% Total time: 1133.48 secs.
fclose(fid);
Run Code Online (Sandbox Code Playgroud)
我还要感谢 Matlab 论坛上的 OCDER 提供的帮助:链接