Help to make a code faster/memory efficient

3 次查看(过去 30 天)
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.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 GPU Computing in MATLAB 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by