Speeding up code
Mostrar comentarios más antiguos
I've written a code to calculate three numbers for me, however with the first for loop it takes forever to run compared to without it. I know it is over a large range but I was wondering if there was anyway to speed it up?
C_pd = Specific_Heat(T_d,X_d);
C_pb = Specific_Heat(T_b,X_b);
e = 0.1;
f = e;
g = 0.01;
i = 1;
k = 0;
l = 100;
m = k;
n = l;
for j=1:3
for T_f = k:e:l
C_pf = Specific_Heat(T_f,X_f);
a = M_f*C_pf*(T_f-T_cw);
for T_o = m:f:n
b = M_d*C_pd*(T_d-T_o) + M_b*C_pb*(T_b-T_o);
if abs(a-b)<g
T(1,i) = T_f;
T(2,i) = T_o;
i=i+1;
end
end
end
k = min(T(1,:));
l = max(T(1,:));
m = min(T(2,:));
n = max(T(2,:));
e = e/10;
f = f/10;
g = g/10;
end
The idea of this code is to calculate the three variables, starting with a range of 0:100 until they converge. I know the answers are supposed to be T_f = 68 and T_o = 36 however am currently getting no where near those as it is taking too long to converge.
Thanks in advance
Respuesta aceptada
Más respuestas (3)
Daniel Shub
el 23 de Nov. de 2011
Using these parameters
Specific_Heat = @(x,y)(1);
T_d = 1;
X_d = 1;
T_b = 1;
X_b = 1;
X_f = 1;
M_f = 1;
T_cw = 1;
M_d = 1;
M_b = 1;
The code takes 100 ms to run on my computer. While there are a number of ways of speeding up the code you gave us (e.g, initializing T and replacing the T_o for loop with a parfor loop), I think the bottleneck is probably with you Specific_Heat function.
Have you tried profiling your code?
doc profile
3 comentarios
Thomas Humphrey
el 23 de Nov. de 2011
Thomas Humphrey
el 23 de Nov. de 2011
Daniel Shub
el 23 de Nov. de 2011
Don't worry about profiling or parfor loops yet. I timed it with tic and toc (doc tic). When you say you replaced specific_heat, does that mean you replaced
C_pf = Specific_Heat(T_f,X_f);
with
C_pf = 1;
Hin Kwan Wong
el 23 de Nov. de 2011
0 votos
Parfor is not really beneficial unless you have quad cores or comput clusters. Looking at your code it will benefit a lot from vectorization instead.
Please read: "Techniques for Improving Performance" in MATLAB help. I learnt a lot from there and the profiler is very helpful. My code had 200x speed improvement.
First you need to make sure Specific_Heat supports vector as inputs. Then you start vectorizing the inner most for loop and work your way back
3 comentarios
Daniel Shub
el 23 de Nov. de 2011
I would argue that many computers have 2+ cores nowadays. It is possible the OP is running the code on old hardware, such that the easiest improvement is to get a faster computer.
MATLAB has substantially improved the handling of loops. It is no longer enough to simply assume that vectorizing code will speed up code.
Thomas Humphrey
el 23 de Nov. de 2011
Hin Kwan Wong
el 23 de Nov. de 2011
I don't agree Daniel. This is because I have a dual core PC, and parfor runs actually slower with 2 worker even though I followed proper recommendations. The overhead depends on the nature of the operations in the for loop.
MATLAB as of 2010b is still notoriously slow with for loop. I optimised my code which contains intensive calculation which repeats over 835,000,000 times element by element for a input vector of size 1000. After vectorization there is still 835000 nested function loops but it ran much quicker, I had gained a factor of 200 times improvement in computation time after vectorizing. I measured it with tic toc and I am not bluffing. This was done a week ago when I was enlightened and educated by the help file. It's a very helpful read.
Daniel Shub
el 23 de Nov. de 2011
I missed it in my first answer ...
The variable T is growing in your inner loop. I got distracted by the i, and thought it would only grow a little bit. What is happening is that every time abs(a-b) < g, you need to allocate a new memory buffer for T that is one slot bigger than the current T. Then you need to copy the old T into the new memory buffer and finally add the new element in. This is hugely time consuming as the size of T grows.
You need to preallocate T in some way. Assuming 1 loop is speedy enough, and that you only want 1000 loops something like
C_pd = Specific_Heat(T_d,X_d);
C_pb = Specific_Heat(T_b,X_b);
e = 0.1;
f = e;
g = 0.01;
%i = 1; % This is moved to later
k = 0;
l = 100;
m = k;
n = l;
T = []; % This is new
for j=1:3
i = 1; % Moved from earlier
Ttemp = []; % This is new
for T_f = k:e:l
C_pf = Specific_Heat(T_f,X_f);
a = M_f*C_pf*(T_f-T_cw);
for T_o = m:f:n
b = M_d*C_pd*(T_d-T_o) + M_b*C_pb*(T_b-T_o);
if abs(a-b)<g
Ttemp(1,i) = T_f; % This has been renamed
Ttemp(2,i) = T_o; % This has been renamed
i=i+1;
end
end
end
T = [T, Ttemp]; % This is new
k = min(T(1,:));
l = max(T(1,:));
m = min(T(2,:));
n = max(T(2,:));
e = e/10;
f = f/10;
g = g/10;
end
3 comentarios
Thomas Humphrey
el 23 de Nov. de 2011
Thomas Humphrey
el 23 de Nov. de 2011
Daniel Shub
el 23 de Nov. de 2011
Sorry about that. Try the edited version of the answer.
Categorías
Más información sobre MATLAB Parallel Server en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!