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

 採用された回答

Thomas Humphrey
Thomas Humphrey 2011 年 11 月 26 日

0 投票

Just found the answer
buy the parallel computing toolbox.
Was able to solve this with 100 iterations of my code (the first for loop run 100 times) in less than a second as soon as this was purchased (cost £18)
before that it was taking over 20 seconds to do 3 loops.
can finally use my i7 to its full potential

その他の回答 (3 件)

Daniel Shub
Daniel Shub 2011 年 11 月 23 日

0 投票

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 件のコメント

Thomas Humphrey
Thomas Humphrey 2011 年 11 月 23 日
sorry I'm still fairly new to matlab. I haven't tried profiling, and am not sure how to use a parfor loop.
I have tried taking the specific_heat function out of the loops and using a fixed value and the code still takes just as long.
Can i asked how you were able to time it?
Thanks
Thomas Humphrey
Thomas Humphrey 2011 年 11 月 23 日
Also the specific_heat script has to be inside the loop as it is dependent on T_f for this iteration.
The function runs fairly quickly until I introduced the outside for loop (for j=1:3)
and then it slowed down hugely, and I currently don't even want to attempt to run it more then 3 times, however ideally I need to run this anything up to 1000 times until I get one single answer for all variables (T_f, T_o, C_pf)
Daniel Shub
Daniel Shub 2011 年 11 月 23 日
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
Hin Kwan Wong 2011 年 11 月 23 日

0 投票

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 件のコメント

Daniel Shub
Daniel Shub 2011 年 11 月 23 日
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
Thomas Humphrey 2011 年 11 月 23 日
the first computer I ran this on has 4 GB 1333 MHz DDR3 ram with a 1.8 GHz i7 processor.
I then transferred it to my main computer. This has 16 GB 1333 MHz DDR3 ram and a 3.4 GHz i7 2600k, so I doubt it is the computer.
Having said that I have noticed that although matlab will use up all of my RAM on my laptop (4gb i7) it will only use around 1/4 of the cpu.
I didn't replace the specific_heat script i just simply gave it a fixed value outside of the for loop so it didn't change for each value of T_f.
I will have to read that document, From memory the script does allow vectors to be the input.
Thanks
Hin Kwan Wong
Hin Kwan Wong 2011 年 11 月 23 日
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
Daniel Shub 2011 年 11 月 23 日

0 投票

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 件のコメント

Thomas Humphrey
Thomas Humphrey 2011 年 11 月 23 日
you mean like this?
C_pd = Specific_Heat(T_d,X_d);
C_pb = Specific_Heat(T_b,X_b);
e = 0.01;
f = 0.01;
g = 0.001;
k = 0;
l = 100;
m = k;
n = l;
T1 = clock;
Tfinal = [];
for j=1:2
i = 1;
T = [];
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);
% ceepf(i)=C_pf;
if abs(a-b)<g
Tfinal = [Tfinal,T];
T_F(i) = T_f;
T_O(i) = T_o;
% aa(i)=a;
% bb(i)=b;
i=i+1;
end
end
end
i = 1;
k = min(T_F);
l = max(T_F);
m = min(T_O);
n = max(T_O);
e = e/10;
f = f/10;
g = g/10;
end
Have just tried this and it is running just as slow
Thomas Humphrey
Thomas Humphrey 2011 年 11 月 23 日
in fact, I think this is running slower then before.
Daniel Shub
Daniel Shub 2011 年 11 月 23 日
Sorry about that. Try the edited version of the answer.

サインインしてコメントする。

カテゴリ

ヘルプ センター および File Exchange で Programming についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by