How to make a submatrix assignment faster?
6 次查看(过去 30 天)
显示 更早的评论
Hello,
I have question regarding the required computional time of submatrix assignments. The code I used so far looks like this:
B_tot(1:6,pos:pos+2) = [ddx 0 0;0 ddy 0;0 0 ddz;ddy ddx 0;0 ddz ddy;ddz 0 ddx];
I started to use the profiler because I run some time consuming simulation programs. It turned out that this line was, using a smaller example, consuming 3.91s (executed more than 800,000 times). I replaced the sub matrix assigment by single assignments:
B_tot(1,pos) = ddx;
B_tot(2,pos+1) = ddy;
B_tot(3,pos+2) = ddz;
B_tot(4,pos) = ddy;
B_tot(4,pos+1) = ddx;
B_tot(5,pos+1) = ddz;
B_tot(5,pos+2) = ddy;
B_tot(6,pos) = ddz;
B_tot(6,pos+2) = ddx;
This code only takes 0.22s. I made small comparison and also tried to use a small function to reduce the clutter which the single assignments introduced:
tic
for i = 1:10000
B_tot = zeros(6,24);
for j = 1:8
ddx = 1;
ddy = 2;
ddz = 3;
pos = j*3-2;
B_tot(1:6,pos:pos+2) = [ddx 0 0;0 ddy 0;0 0 ddz;ddy ddx 0;0 ddz ddy;ddz 0 ddx];
end
end
toc
tic
for i = 1:10000
B_tot = zeros(6,24);
for j = 1:8
ddx = 1;
ddy = 2;
ddz = 3;
pos = j*3-2;
B_tot = assign_sub_B(B_tot,pos,ddx,ddy,ddz);
end
end
toc
tic
for i = 1:10000
B_tot = zeros(6,24);
for j = 1:8
ddx = 1;
ddy = 2;
ddz = 3;
pos = j*3-2;
B_tot(1,pos) = ddx;
B_tot(2,pos+1) = ddy;
B_tot(3,pos+2) = ddz;
B_tot(4,pos) = ddy;
B_tot(4,pos+1) = ddx;
B_tot(5,pos+1) = ddz;
B_tot(5,pos+2) = ddy;
B_tot(6,pos) = ddz;
B_tot(6,pos+2) = ddx;
end
end
toc
function B = assign_sub_B(B,pos,ddx,ddy,ddz)
B(1,pos) = ddx;
B(2,pos+1) = ddy;
B(3,pos+2) = ddz;
B(4,pos) = ddy;
B(4,pos+1) = ddx;
B(5,pos+1) = ddz;
B(5,pos+2) = ddy;
B(6,pos) = ddz;
B(6,pos+2) = ddx;
end
The result is:
Elapsed time is 0.299077 seconds.
Elapsed time is 0.035045 seconds.
Elapsed time is 0.011723 seconds.
My question is now: can I somehow write the single assigments in a nicer way which uses comparable computation time? Or can I make the function "assign_sub_B" in some way to pass the matrix B by reference to manipulate it directly? At the moment it generates a copy which makes it still slow (3x slower than single assignments). My simulations take multiple hours to days and I try to squeeze out as much as I can.
0 个评论
回答(1 个)
Jan
2018-4-30
I do not understand, what your question is. You found out already, that assigning the scalars is much faster than creating the temporary matrix and inserting it into the other matrix. This is a correct observation. Calling a dedicated function to do this has a certain overhead also. In addition a deep data copy of B is created for each call.
There might be a tiny improvement if you process the array in columnwise order:
B_tot(1, pos) = ddx;
B_tot(4, pos) = ddy;
B_tot(6, pos) = ddz;
pos1 = pos + 1;
B_tot(2, pos1) = ddy;
B_tot(4, pos1) = ddx;
B_tot(5, pos1) = ddz;
pos2 = pos + 2;
B_tot(3, pos2) = ddz;
B_tot(5, pos2) = ddy;
B_tot(6, pos2) = ddx;
I'm not sure if this has a measurable effect, but in theory it is faster.
This hard coded data insertion is really ugly, but efficient. Add a comment, what this code does:
% Efficient version of:
% B_tot(1:6,pos:pos+2) = [ddx 0 0;0 ddy 0;0 0 ddz;ddy ddx 0;0 ddz ddy;ddz 0 ddx];
...
And to post a real answer:
How to make a submatrix assignment faster?
Your method looks very efficient already. If you need more speed, try to move some computations to C-Mex functions. Converting your assign_sub_B to a C-mex does not help, because the deep data copy will still be a problem.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Beamforming 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!