How to obtain fast memory copy of portions in a matrix

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)

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).
Matt J
Matt J on 31 Oct 2012
Edited: Matt J on 31 Oct 2012
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

Asked:

on 31 Oct 2012

Community Treasure Hunt

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

Start Hunting!