Filter löschen
Filter löschen

Help to make a code faster/memory efficient

3 Ansichten (letzte 30 Tage)
Fernando
Fernando am 11 Sep. 2017
Bearbeitet: Cedric am 12 Sep. 2017
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

Akzeptierte Antwort

Cedric
Cedric am 11 Sep. 2017
Bearbeitet: Cedric am 11 Sep. 2017
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 Kommentare
Fernando
Fernando am 12 Sep. 2017
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 am 12 Sep. 2017
My pleasure!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Community Treasure Hunt

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

Start Hunting!

Translated by