How do I make this function run faster?

조회 수: 7 (최근 30일)
Apurva
Apurva 2020년 5월 21일
댓글: Apurva 2020년 5월 22일
What this function does:
I have variables defined on a mesh. Given one of the variables (called 'fieldvar'), this function iterates over every cell of the mesh, iterates over every face of a cell, finds the neighbouring cell. Fetches data of that cell and interpolates to a required degree (given by 'order_new'). Finally, assigns one its faces to 'neigb' and returns it.
Problem:
This funtion is called many times and is unusably slow.
Function definition:
function neighb = neighbour2D(fieldvar)
% function neighb = neighbour2D(fieldvar)
% Purpose: Compute the neighbouring values of fieldvar for every cell commensurate to the order
% demanded. Return array equivalent to e.g. Ez(vmapP), i.e. values of the
% neighbouring cells as a flat array, where every cell contributes
% Nfp*Nfaces no. of entries. Here, the Nfp is acc. to order_new.
Globals2D;
neighb=zeros(length(vmapM),1);
count=0;
for k=1:K
kself1=fI(k,1); kself2=fI(k,2);
one=ones(1,Nfp(order_new(k)));
fmask_local = Fmask{order_new(k)};
for f=1:Nfaces
% find neighbor
kneigh = EToE(k,f); fneigh = EToF(k,f);
knei1 = fI(kneigh,1); knei2 = fI(kneigh,2);
val=interp{order_new(kneigh),order_new(k)}*fieldvar(knei1:knei2);
val=val(fmask_local); val=val(:,fneigh);
% reference length of edge
v1 = EToV(k,f); v2 = EToV(k, 1+mod(f,Nfaces));
refd = sqrt( (VX(v1)-VX(v2))^2 + (VY(v1)-VY(v2))^2 );
% find volume node numbers of left and right nodes
xself = x(kself1:kself2); yself = y(kself1:kself2);
xneig = x(knei1:knei2); yneig = y(knei1:knei2);
x1=xself(fmask_local); x1=x1(:,f);
x2=interp{order_new(kneigh),order_new(k)}*xneig;
x2=x2(fmask_local); x2=x2(:,fneigh);
y1=yself(fmask_local); y1=y1(:,f);
y2=interp{order_new(kneigh),order_new(k)}*yneig;
y2=y2(fmask_local); y2=y2(:,fneigh);
x1=x1*one; x2=x2*one; y1=y1*one; y2=y2*one;
% Compute distance matrix
D = (x1-x2').^2 + (y1-y2').^2;
[row,~]=find(sqrt(abs(D))<NODETOL*refd);
neighb(count+1:count+length(val(row)))=val(row);
count=count+length(val(row));
end
end
return
Here's what the profiler says:
Lines where the most time was spent
Line Number Code Calls Total Time % Time Time Plot
43 neighb(count+1:count+length(va... 776520 2.198 s 15.3%
42 [row,~]=find(sqrt(abs(D))<N... 776520 1.601 s 11.1%
21 val=interp{order_new(kneigh),o... 776520 1.020 s 7.1%
22 val=val(fmask_local); val=val(... 776520 0.982 s 6.8%
36 y2=y2(fmask_local); y2=y2(:,fn... 776520 0.974 s 6.8%
All other lines 7.611 s 52.9%
  댓글 수: 6
Rik
Rik 2020년 5월 22일
The point is that you are storing data in that vector. If it is not large enough yet, Matlab will have to copy the array to extend it, which is very slow.
A=zeros(1,3);
A(1:4)=1:4;%A was too small
Apurva
Apurva 2020년 5월 22일
Oh, got it. Yes, I've prealloacted it to the correct size. No implicit expansion should be required.
neighb=zeros(length(vmapM),1);

댓글을 달려면 로그인하십시오.

답변 (0개)

카테고리

Help CenterFile Exchange에서 Interpolation에 대해 자세히 알아보기

제품


릴리스

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by