matlab代码在加载netcdf数据时变慢

kuuvgm7e  于 2023-03-03  发布在  Matlab
关注(0)|答案(1)|浏览(127)
    • 代码**:

我需要绘制一个大的netcdf文件中的数据图,文件大小为1080*171*52*120(经度、纬度、深度、时间),我的策略是在第一维中加载12个数据块,在第四维中加载36个数据块(参见 * 脚本末尾 *)。
所以,我有一个for循环在12个空间块上,它包含一个for循环在36个时间块上,在时间块上的每次迭代中,我把我需要的信息存储在一个矩阵V中,然后绘图。

    • 问题是:**

代码的速度似乎在几次迭代后变慢。发生这种情况的迭代次数不是恒定的...通常为5或8次。速度变慢似乎不是由于内存问题,因为在第一次迭代后分配的内存是恒定的。问题似乎是由于加载数据(* via * ncread)。然而,我上传的数据的大小对于所有的迭代都是恒定的...
这里是"memory * 在减速之前 * 的输出以及加载文件所用的时间:
最大可能阵列:23186 MB(2.431e +10字节)* 可用于所有阵列的内存:23186 MB(2.431e +10字节)* MATLAB使用的内存:1226 MB(1.286e +09字节)物理内存(RAM):16296兆字节(1.709e +10个字节)

  • 受可用系统内存(物理内存+交换文件内存)的限制。运行时间为0.384304秒。

而这里相同的输出 * 在减速之后
最大可能阵列:23186 MB(2.431e +10字节)
可用于所有阵列的内存:23186 MB(2.431e +10字节)* MATLAB使用的内存:1226 MB(1.286e +09字节)物理内存(RAM):16296兆字节(1.709e +10个字节)

  • 受可用系统内存(物理内存+交换文件内存)的限制。已用时间为26.155781秒。

"* 让事情更混乱..."
每个时间块由5个时间点组成。这些时间点的索引存储在一个单元数组(new_inds)的每个单元中,该数组具有120/5个元素。但是,如果我将该单元数组的长度限制为8(或8 * 5个时间点),代码不会变慢。
实际上,在最后一种情况下,加载时间在整个执行过程中实际上是恒定的:
最大可能阵列:23068 MB(2.419e +10字节)* 可用于所有阵列的内存:23068 MB(2.419e +10字节)* MATLAB使用的内存:1231 MB(1.291e +09字节)物理内存(RAM):16296兆字节(1.709e +10个字节)

  • 受可用系统内存(物理内存+交换文件内存)的限制。运行时间为0.390843秒。

请注意,在最后一种情况下,要上传的块的大小与以前相同。因此,即使我显然期望代码总体上运行得更快(因为总共有更少的时间点),我也不明白为什么在最后一种情况下加载工作得很好。

    • 问题:**

这两种情况下唯一不同的是包含时间索引的单元格数组的长度,但我真的怀疑这是否是速度变慢的原因......还因为在第一种情况下,matlab在非恒定的迭代次数后变得懒惰。
有人能理解其中的原因吗?

    • 脚本:**
TT=length(new_inds);%how many time steps to average at each iteration

%%%plotting by chunk
figure;hold on

for kkk=1:numel(chunks)-1   %iteration on space
V=0;   %matrix to update after each iteration on time    

for ttt=1:TT   %iteration on time

fprintf(['LOADING -',num2str(ttt),'/',num2str(TT),'- STARTED!\r'])

s=chunks(kkk+1)-chunks(kkk) %size in space of the current chunk
t=new_inds{ttt}(end)-new_inds{ttt}(1)+1  %size in time of the current chunk
memory 
tic 
%load the velocitites on the current chunk
Uvel=ncread(uvelnc,'Uvel',[chunks(kkk) 1 1 new_inds{ttt}(1)],...
    [chunks(kkk+1)-chunks(kkk)+2 y2 Inf new_inds{ttt}(end)-new_inds{ttt}(1)+1]);

Vvel=ncread(vvelnc,'Vvel',[chunks(kkk) 1 1 new_inds{ttt}(1)],...
    [chunks(kkk+1)-chunks(kkk)+2 y2 Inf new_inds{ttt}(end)-new_inds{ttt}(1)+1]);

Uvel(Uvel==-9999)=NaN;
Vvel(Vvel==-9999)=NaN;
toc

fprintf(['LOADING -',num2str(ttt),'/',num2str(TT),'- DONE!\r'])

%%%velocity module
Uvel= nansum(Uvel,4);
Vvel= nansum(Vvel,4);

[Xv,Yv,Zv]=ndgrid(lonMv(chunks(kkk):chunks(kkk+1)-1+2),latMv(1,:),uv_levs);
[Xu,Yu,Zu]=ndgrid(lonMu(chunks(kkk):chunks(kkk+1)-1+2),latMu(1,:),uv_levs);
Vvel=interpn(Xv,Yv,Zv,Vvel,Xu,Yu,Zu,'linear',NaN);

V = V + sqrt(Uvel.^2+Vvel.^2); %update the matrix V
end %of the iteration on time

V_t=V/sum(cellfun('length',new_inds)); %average V on time

%%%plotting
V_t=V_t(:,:,1); %surface values

lonP=lonMu(chunks(kkk):chunks(kkk+1)-1+2,:);
lonP(V_t==0)=NaN;
latP=latMu(chunks(kkk):chunks(kkk+1)-1+2,:);
m_pcolor(lonP,latP,V_t); 

end %iteration on space
toe95027

toe950271#

使用低级函数 * netcdf.getVar * 可能会有所帮助

相关问题