Speeding up code
古いコメントを表示
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
採用された回答
その他の回答 (3 件)
Daniel Shub
2011 年 11 月 23 日
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
2011 年 11 月 23 日
Thomas Humphrey
2011 年 11 月 23 日
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
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
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
2011 年 11 月 23 日
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
2011 年 11 月 23 日
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
2011 年 11 月 23 日
Thomas Humphrey
2011 年 11 月 23 日
Daniel Shub
2011 年 11 月 23 日
Sorry about that. Try the edited version of the answer.
カテゴリ
ヘルプ センター および File Exchange で MATLAB Parallel Server についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!