reduce memory for matrix multiplication
이전 댓글 표시
Hi dudes, I have 2 vectors multiplied by a 1e4*1e4 matrix as below example:
A = 1:1:10000;
B = rand(10000);
C = (1:1:10000)';
an I have a result matrix like D, each array of which are obtained by the multiplication of these matrices as below:
D(each array) = A*(B*C);
the size of D matrix is 11*11 or larger, meaning that I should do this multiplication 121 times or more consuming large memory and time. Any Idea how to optimize the multiplication process?
댓글 수: 19
KALYAN ACHARJYA
2018년 10월 22일
Jan
2018년 10월 22일
I do not understand the question. The multiplication (1x1e4)*(1e4x1e4)*(1e4x1) returns a scalar. So what does "each array" mean? Where does "11x11" come from? Why do 121 of these not really huge matrix multiplications consume too much memory or time? Please post the relevant part of the code and explain, how much time it needs and your requirements. Currently I guess, it is another part of your code, which slows down the processing.
Matt J
2018년 10월 22일
I have 2 vectors multiplied by a 4*4 matrix
4x4? Looks like 1e4 x 1e4 to me.
behzad
2018년 10월 22일
behzad
2018년 10월 22일
behzad
2018년 10월 22일
behzad
2018년 10월 22일
Bruno Luong
2018년 10월 22일
편집: Bruno Luong
2018년 10월 22일
Without further assumptiions, there is nothing that can be reduced here obviously, the big part of memory is taken by the storage of B, and the time is taken by matrix x vector product. Those are "basic" arithmetic operations that MATLAB is good at.
James Tursa
2018년 10월 22일
편집: James Tursa
2018년 10월 22일
Are all of your "different" A, B, and C in memory at the same time? Or are they generated within the loop?
I'm with Bruno ... MATLAB probably already does the A*(B*C) calculation itself in the best way possible. But multi-threading the loop (e.g. via a mex routine) might speed things up overall.
James Tursa
2018년 10월 22일
편집: James Tursa
2018년 10월 22일
"... B is part of a bigger matrix ..."
Are you extracting B from this bigger matrix each iteration within the loop? This requires a data copy at the m-code level but could potentially be avoided in a mex routine. Is it the same extraction each time? What are the details of this? (i.e., what is the size of this bigger matrix and which exact part are you extracting each iteration?)
Bruno Luong
2018년 10월 22일
This is a most pertinent information and MEX might be able to help you to not create B internal data at all and perform matrix vector product directly from F.
Is it the same for A and C? Are they also extracted from some larger vectors Va,Vc according to
Va(k1+1:k1+10000);
Vc(k2+1:k2+10000);
behzad
2018년 10월 22일
behzad
2018년 10월 22일
James Tursa
2018년 10월 22일
편집: James Tursa
2018년 10월 22일
So, would you way that your pseudo-code is really something like this:
A = zeros(11,11); D = A;
F = some large matrix (fixed value for the loop)
k1 = some integer (fixed value for the loop)
k2 = some integer (fixed value for the loop)
for q = 1:200
for p = 1:1:121
A = rand(1,10000); % some calculation that changes each time
B = F(k1+1:k1+10000,k2+1:k2+10000);
C = rand(10000,1); % some calculation that changes each time
D(p) = A*(B*C);
end
A = D + A;
end
I.e., B can obviously be pulled out of the loop in the above code and the data copy only done once. It is critical to know which things change during the loop and which things don't.
We can help you with the C mex stuff, but only if it really makes sense, and we won't know that until we know exactly how the pseudo code looks.
답변 (2개)
One possibility might be to zero-pad A and C, embedding them in larger sparse vectors to be multiplied with F. This way you don't have to pull B out of F and allocate separate memory for it.
Za=spalloc(1,size(F,1), 1e4);
Zc=spalloc(size(F,2),1,1e4);
for p = 1:121
A = ...
Apad=Za;
Apad(k1+1:k1+1e4)=A;
C=...
Cpad=Zc;
Cpad(k2+1:k2+1e4)=C;
D(p) = Apad*(F*Cpad);
end
댓글 수: 9
Bruno Luong
2018년 10월 22일
편집: Bruno Luong
2018년 10월 22일
I like it, sound clever. Though I'm not sure about what is the advantage of using sparse vector.
Bruno Luong
2018년 10월 22일
편집: Bruno Luong
2018년 10월 22일
And it might be worse because the BLAS for full matrix is replaced by a less-efficient sparse algorithm. But it just a guess.
EDIT: I tested both with tic/toc, for the same size sparse is twice slower than full.
Matt J
2018년 10월 22일
With how much padding?
Bruno Luong
2018년 10월 22일
zero.
I think it depends a lot on F.
N=3e4+1;
F=eye(N);
x=ones(1e4,1); x(N)=0;
xs=sparse(x);
tic; %full
ans=x.'*(F*x)+7;
toc;
%Elapsed time is 2.279681 seconds.
tic; %sparse
ans=xs.'*(F*xs)+7;
toc;
%Elapsed time is 0.274425 seconds.
Bruno Luong
2018년 10월 23일
편집: Bruno Luong
2018년 10월 23일
Mainly because I guess you set F is EYE, not realistic. Here is my test results
size(F)=10011
FULL : 0.01708 seconds
SPARSE : 0.07347 seconds
INPLACE: 0.04690 seconds
size(F)=30000
FULL : 0.15706 seconds
SPARSE : 0.26915 seconds
INPLACE: 0.04871 seconds
Code:
N=3e4;
F=rand(N);
A = rand(1,1e4);
C = rand(1e4,1);
[m,n] = size(F);
Ae = A;
Ae(m) = 0;
Aes=sparse(Ae);
Ce = C;
Ce(n) = 0;
Ces=sparse(Ce);
tic; %full
D=Ae*(F*Ce);
t1=toc;
tic; %sparse
D = Aes*(F*Ces);
t2=toc;
tic % inplace
k1 = 1;
k2 = 1;
AFk = zeros(1,size(C,1));
for k=1:length(AFk)
Fk = mxCreateSharedMatrix2018(F,k1+(k2+k-1)*m,size(A,2),1);
AFk(k) = A*Fk;
end
mxUnshareMatrix2018(Fk,[],1);
clear Fk
D = AFk*C; % 0.048428 seconds.
t3=toc;
fprintf('size(F)=%d\n', N);
fprintf('\tFULL : %1.5f seconds\n', t1);
fprintf('\tSPARSE : %1.5f seconds\n', t2);
fprintf('\tINPLACE: %1.5f seconds\n', t3);
Matt J
2018년 10월 23일
OK, how about this:
N=4e4+1;
F=ones(N);
x=ones(1e4,1); x(N)=0;
xs=sparse(x);
tic; %full
ans=x.'*(F*x)+7;
toc;
%Elapsed time is 0.428139 seconds.
tic; %sparse
ans=xs.'*(F*xs)+7;
toc;
%Elapsed time is 0.374981 seconds.
Bruno Luong
2018년 10월 23일
The result with my PC on your code
FULL: Elapsed time is 0.278291 seconds.
SPARSE: Elapsed time is 0.360029 seconds.
Of course you can try to increase N where at the limit become favorable more and more to sparse.
Bruno Luong
2018년 10월 22일
편집: Bruno Luong
2018년 10월 24일
If you are using R2018a/b you can use the MEX file attached here to avoid forming B. The matrix-vector product is replaced by a loop on vector x vector, it can be slower than MATLAB (twice according to my test).
[m,n] = size(F);
AFk = zeros(1,size(C,1));
for k=1:length(AFk)
Fk = mxCreateSharedMatrix2018(F,k1+(k2+k-1)*m,size(A,2),1);
AFk(k) = A*Fk;
end
mxUnshareMatrix2018(Fk,[],1);
clear Fk
D = AFk*C; % or set D(k1,k2)?
댓글 수: 2
Jan
2018년 10월 24일
@Bruno: The link is dead.
Bruno Luong
2018년 10월 24일
OK Jan, I attached the code directly
카테고리
도움말 센터 및 File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!