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!