Help to make a code faster/memory efficient

조회 수: 2 (최근 30일)
Fernando
Fernando 2017년 9월 11일
편집: Cedric 2017년 9월 12일
Dear all, I am trying to improve the computation speed/memory usage of a code I've done for a electromagnetism problem. I have converted the arrays to single values which has helped a bit and also tried converting to gpuArrays but this seems slower. I've copied the most time consuming part of my code, other parts are coded similarly so any suggestion in this piece of code would be helpful. It seems the cross product calculation consumes a lot of time, I think maybe using something like pagefun, arrayfun? but I have no idea how to convert this to that. Any ideas would be deeply appreciated.
magnetic=zeros(19128960,3,'single');
for u = 1:2592
for n = 1:7380
q =1+(n-1)+(7380*(u-1));
magne1=cross((PosS(n,:)-PosSeg1(u,:)),(ExtPosSeg1(u,:)-PosSeg1(u,:)));
magnetic(q,1)=magne1(:,1);
magnetic(q,2)=magne1(:,2);
magnetic(q,3)=magne1(:,3);
end
end

채택된 답변

Cedric
Cedric 2017년 9월 11일
편집: Cedric 2017년 9월 11일
Check this out:
n1 = 7380 ;
n2 = 2592 ;
PosS = rand( n1, 3 ) ;
PosSeg1 = rand( n2, 3 ) ;
ExtPosSeg1 = rand( n2, 3 ) ;
Loop-based:
tic ;
magnetic=zeros(n1*n2, 3,'single');
for u = 1:n2
for n = 1:n1
q =1+(n-1)+(n1*(u-1));
magne1=cross((PosS(n,:)-PosSeg1(u,:)),(ExtPosSeg1(u,:)-PosSeg1(u,:)));
magnetic(q,1)=magne1(:,1);
magnetic(q,2)=magne1(:,2);
magnetic(q,3)=magne1(:,3);
end
end
toc
outputs
Elapsed time is 86.585071 seconds.
and here is a vector version
tic ;
magnetic_CW = reshape( permute( cross( ...
bsxfun( @minus, permute( PosS, [3,2,1] ), PosSeg1 ), ...
repmat( ExtPosSeg1 - PosSeg1, 1, 1, n1 )), [2,3,1] ), 3, [] ).' ;
toc
outputs
Elapsed time is 2.267693 seconds.
Both outputs are equal:
isequal( magnetic, single( magnetic_CW ))
ans =
logical
1
No need to convert to single, however, I did it for the comparison.
Cheers,
Cedric
NOTES
  1. It looks awfully complicated because I wanted to avoid creating intermediary variables, but what we do is just a cross product on two 3D arrays, one containing PosS-PosSeg1 for all columns of both (hence the call to BSXFUN), and the second being the corresponding 3D array of ExtPosSeg1-PosSeg1. All the rest is about permuting/reshaping/repeating so dimensions are appropriate.
  2. You may not need to work with 2D arrays actually, and you can probably eliminate the external RESHAPE and PERMUTE operations.
  댓글 수: 5
Fernando
Fernando 2017년 9월 12일
Oh I understand now.
Thanks a lot, I have managed to implement this vectorization in the different calculations of that for loop in my code, now it works 140 times faster in that part. Thanks a lot.
Cedric
Cedric 2017년 9월 12일
My pleasure!

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

추가 답변 (0개)

카테고리

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

Community Treasure Hunt

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

Start Hunting!

Translated by