How to obtain fast memory copy of portions in a matrix
Show older comments
Hi All
I have the following problem. I create a large matrix that is MxN in size. The matrix I create can have sizes of 1000x200000.The values are almost symmetric about the center in the following way:
[0 0 1 2 3 4;
0 5 6 7 8 9;
1 2 3 4 0 0];
To avoid calculating duplicates, I only calculate the lower half, and then copy the lines to the upper half.
However, getting this done fast is tricky. I currently use the following code:
for n = nDiag + 2 : 2 * nDiag + 1
nStart1 = max( n - nDiag, 0 );
nEnd1 = min( N - nDiag + n - 1, N);
nStart2 = max( -n, 0 ) + 1;
nEnd2 = min( N + nDiag - n + 1, N);
mA( n, nStart2 : nEnd2 ) = mA( 2 * nDiag - n + 2, nStart1 : nEnd1 );
end;
where mA is the matrix, nDiag is the diagonal size and M = 2 * nDiag + 1. N is the number of rows, same as the definition in the first line.
The original value contains a square root and some hankel calculations on a GPU, taking a total of 25 seconds to calculate. The memory copy takes 17 seconds, which I find way too much.
Can anybody offer any ideas on how to improve that?
Best regards
Henrik Andresen
Answers (2)
James Tursa
on 31 Oct 2012
0 votes
I would expect a mex routine might be able to improve the time to copy, maybe by as much as 1/2 since the explicit sub-matrix mA(2*nDiag-n+2,nStart1:nEnd1) would not have to be formed (which is essentially an extra copy at each iteration of the loop in your posted code).
It might help if you vectorize some of this:
nrange=nDiag + 2 : 2 * nDiag + 1;
Start1=max(nrange-nDiag,0);
End1 = min( N - nDiag + nrange - 1, N);
Start2= max( -nrange, 0 ) + 1;
End2=Start2+(End1-Start1);
rowdat=2 * nDiag - nrange + 2;
i=0;
for n=nrange
i=i+1;
mA( n, Start2(i) : End2(i) ) = mA( rowdat(i), Start1(i) : End1(i) );
end
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!