Speeding up code
Show older comments
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
Accepted Answer
More Answers (3)
Daniel Shub
on 23 Nov 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 Comments
Thomas Humphrey
on 23 Nov 2011
Thomas Humphrey
on 23 Nov 2011
Daniel Shub
on 23 Nov 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
on 23 Nov 2011
0 votes
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 Comments
Daniel Shub
on 23 Nov 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
on 23 Nov 2011
Hin Kwan Wong
on 23 Nov 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
on 23 Nov 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 Comments
Thomas Humphrey
on 23 Nov 2011
Thomas Humphrey
on 23 Nov 2011
Daniel Shub
on 23 Nov 2011
Sorry about that. Try the edited version of the answer.
Categories
Find more on MATLAB Parallel Server in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!