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.

回答(1 个)

Jan
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.
  1 个评论
Clemens Gebhardt
Clemens Gebhardt 2018-4-30
编辑:Clemens Gebhardt 2018-4-30
Thank you for your answer! My problem was mainly the asthetics, because it expands the code by a couple of lines. I was hoping there was a nicer way to do it which does not require so many repetitions. Seems like I have to live with it. I wish I could at least pass the matrix by reference to a function. Still, thank you! I only wanted to know if there was an alternative solution before rewriting my code. ;-)
Edit: I noticed you calculated the increment of pos in a separate variable. Is the creation of the variable really faster than 2 more times calculating the increment?

请先登录,再进行评论。

标签

产品

Community Treasure Hunt

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

Start Hunting!

Translated by