New ways to speed up a code

7 visualizaciones (últimos 30 días)
Ata
Ata el 8 de Feb. de 2017
Comentada: Ata el 9 de Feb. de 2017
Hello,
I have been given a humongous code (like a toolbox) which has been implemented at 2013 and the problem is, the code is very slow for the kind of simulation I am running.
Initially, I wanted to reimplement everythings in another faster computer language like Fortran, but it is almost impossible since the code is huge... Hence, I did Matlab profiler to find the bottleneck, I vectorised the code and tried to remove any unnecessary function of command. Also, I put some efforts to avoid using matlab functions itself like sqrt or reshape or transpose,..etc. I could save a bit of time, but still no satisfaction.
Could anyone help me to improve the code and speed up? I would really appreciate so.
Here I put the main file of the code to take a look. There might be some experts to help me improve it on.
close all;
clc;
current_directory = pwd;
%--------------------------------------------------------------------------
%{problem,mesh,{CFL,Klim},{mesh_direction,mesh_file,Simulation_direction,Simulation_file,Continue_simulation,!},flag_debug,code}
%--------------------------------------------------------------------------
auto.list = {...
{136,1,{3,0},{0,0,0,0,0,0,0},0,'EL_3D_UNSTR'},... %136,6
};
%--------------------------------------------------------------------------
% Run cases
%--------------------------------------------------------------------------
v_i_curr = zeros(1,length(auto.list));
for i = 1:length(auto.list)
s_root = strcat('C:\Asus\SEED\MatLab code\4fv_code_3D_NCLaw4eqJ+eqH\',auto.list{i}{6});
cd(s_root)
i_problem=auto.list{i}{1};
i_mesh=auto.list{i}{2};
s_prob_mesh = sprintf('problem_%06d_mesh_%d',i_problem,i_mesh);
out=exist(s_prob_mesh,'dir');
if out == 7
auto.list{i}{4}{1}=1;
cd(s_prob_mesh)
out = exist('mesh.mat','file');
if out == 2
auto.list{i}{4}{2}=1;
end
i_debug = auto.list{i}{5};
i_CFL = auto.list{i}{3}{1};
i_Klim = auto.list{i}{3}{2};
if i_debug==0
s_debug='';
auto.input.flag_debug = 0;
elseif i_debug==1
s_debug='debug_';
auto.input.flag_debug = 1;
end
if i_CFL==0
s_CFL = '';
else
s_CFL = sprintf('CFL_%d',i_CFL);
end
if i_Klim==0
s_Klim = '';
else
s_Klim = sprintf('_Klim_%d',i_Klim);
end
s_comp = strcat(s_debug,s_CFL,s_Klim);
auto.input.s_comp = s_comp;
out = exist(s_comp,'dir');
if out == 7
cd(s_comp)
s_file = exist('res.mat','file');
auto.list{i}{4}{3}=1;
if s_file ==2
auto.list{i}{4}{4}=1;
load('res.mat','str')
s = sprintf ('Job %d : existing simulation',i);
disp(s)
disp('---------------------')
s=sprintf('nstep = %d',str.i);
disp(s)
s=sprintf('t = %0.5g',str.t);
disp(s)
s=sprintf('dt= %0.5g',str.dt);
disp(s);
disp(' ')
flag_cont_simul = input('Continue? (1/Yes 0/No)');
auto.list{i}{4}{5} = flag_cont_simul;
v_i_curr(i) = str.i;
if flag_cont_simul ==1
nstep = input('nstep = ');
k_debug = input('k_debug = ');
t_end = input('t_end = ');
auto.list{i}{4}{6}=nstep;
auto.list{i}{4}{7}=k_debug;
auto.list{i}{4}{8}=t_end;
end
if ~isfield(str,'isave_s') %to repair new function
auto.isave_s=250;
end
end
else
s = sprintf ('Job %d : existing mesh, new simulation',i);
disp(s)
disp('----------------------------')
nstep = input('nstep = ');
k_debug = input('k_debug = ');
t_end = input('t_end = ');
auto.list{i}{4}{6}=nstep;
auto.list{i}{4}{7}=k_debug;
auto.list{i}{4}{8}=t_end;
end
else
i_debug = auto.list{i}{5};
i_CFL = auto.list{i}{3}{1};
i_Klim = auto.list{i}{3}{2};
if i_debug==0
s_debug='';
auto.input.flag_debug = 0;
elseif i_debug==1
s_debug='debug_';
auto.input.flag_debug = 1;
end
if i_CFL==0
s_CFL = '';
else
s_CFL = sprintf('CFL_%d',i_CFL);
end
if i_Klim==0
s_Klim = '';
else
s_Klim = sprintf('_Klim_%d',i_Klim);
end
s_comp = strcat(s_debug,s_CFL,s_Klim);
auto.input.s_comp = s_comp;
s = sprintf ('Job %d : new mesh, new simulation',i);
disp(s)
disp('----------------------------')
nstep = input('nstep = ');
k_debug = input('k_debug = ');
t_end = input('t_end = ');
auto.list{i}{4}{6}=nstep;
auto.list{i}{4}{7}=k_debug;
auto.list{i}{4}{8}=t_end;
auto.input.flag_debug = auto.list{i}{5};
end
end
clear str
clear sol
cd(current_directory)
for i=1:length(auto.list)
auto.input.main_code = auto.list{i}{6};
auto.input.problem = auto.list{i}{1};
auto.input.mesh = auto.list{i}{2};
auto.input.comp = auto.list{i}{3};
auto.input.flag_exist_mesh_dir = auto.list{i}{4}{1};
auto.input.flag_exist_mesh_file = auto.list{i}{4}{2};
auto.input.flag_exist_simul_dir = auto.list{i}{4}{3};
auto.input.flag_exist_simul_file = auto.list{i}{4}{4};
auto.input.flag_cont_simul = auto.list{i}{4}{5};
s_root = strcat('C:\Asus\SEED\MatLab code\4fv_code_3D_NCLaw4eqJ+eqH\',auto.input.main_code);
auto.input.s_root = s_root;
%--------------------------------------------------------------------------
% Turn on/off Convergence study
%--------------------------------------------------------------------------
auto.flag_conv_analysis=0;
auto.nstep = auto.list{i}{4}{6};
auto.k_debug = auto.list{i}{4}{7};
auto.t_end = auto.list{i}{4}{8};
auto.k_job = find_jobs_batch_number;
auto.i_curr = v_i_curr(i);
% % % if auto.input.flag_debug == 0
% % % eval(['job' num2str(auto.k_job) ' = batch(''EL_2D_3D_UNSTR_call_start'');' 'write_job_file(auto,job' num2str(auto.k_job) ')'])
% % % else
EL_2D_3D_UNSTR_call_start
% % % end
end

Respuestas (2)

John D'Errico
John D'Errico el 8 de Feb. de 2017
Just my take on the question...
I once was given a rather nasty (and buggy) code to make work, the author not available for consultation. I knew the purpose of the tool, the theory behind it. I spent some time working on the problem, but soon I realized the real solution was to write it myself from scratch. A day later, I had done so, i.e., rewritten the impossible to use code. The result was something we were able to use.
Trying to work with such legacy tools is often not worth the trouble. It becomes a problem of layering patch on top of patch, hack on hack. So that legacy code may be inefficient. Adding hacks to try to make it faster may also be a good way to introduce bugs.
Writing from scratch, with some careful thought to the design can be the best way to speed it up. No, it won't be easy. But it will be far easier than working through code where you don't follow the thought processes of a previous author, now unavailable.
Should you rewrite code in Fortran just to speed it up? Odds are you will spend more time writing the code in Fortran than you would in MATLAB. And odds are good that careful thought in the implementation in MATLAB will be a good way to speed things up.
As for the code you show, it is impossible to guess how to speed it up. We don't know the real purpose of the code, how it is used, where are the bottlenecks. If you insist on trying to improve the existing code, then you want to spend some time learning MATLAB, as well as you can. Yair's book will be worth the read. Spend some serious time using the profile tool on this code. Look for the bottlenecks. Then invest the time to remove them.
Be willing to look for different ways to solve the problems involved. Another example, early in my consulting career, I was tasked with solving a problem by a client. They told me exactly what they wanted done. As it turns out however, what they wanted me to do was to solve a linear system of equations using determinants. Cramer's rule, and all that. They had code for 2 or 3 variables that worked, and they now wanted to solve the problem for 10 unknowns.
My response was there were better ways of solving the problem. So I showed them how to use other tools that still gave them the correct solution, cleanly, and in a reasonable time. All they cared about was getting the correct answer, so they were quite happy.
The point is that legacy methods need not always employ the best way to solve a problem, IF you are willing to think outside the box.
  2 comentarios
Walter Roberson
Walter Roberson el 9 de Feb. de 2017
Earlier in my career, I put in a number of years rewriting software packages while keeping the same basic code -- figuring out how the code worked, what it was supposed to do, what it really did, rewriting pieces at a time to maintain the structure.
Did I mention that I put in a number of years doing that? That is because it takes blooming long.
In each case, when I was finished the several years per project, the code was archived or discarded and never used again. :(
If you are going to put in a few years rewriting a tool, make sure you go open source, so that at least there is a chance someone else might be able to use the code.
Ata
Ata el 9 de Feb. de 2017
Thank you for sharing your experience with me.
I am still struggling though and as I said, not easy to reimplement the code, at least timewise talking.

Iniciar sesión para comentar.


Walter Roberson
Walter Roberson el 8 de Feb. de 2017
reshape() is one of the fastest MATLAB operations. It does not require copying the data; it just changes a header about how the data is to be interpreted. You should not hesitate to use reshape() if it makes the program clearer.
The part of the code you post tells us that your project has a number of different options, has configuration files, and it is related to meshes. That is not enough for us to give any useful information about how to speed up what-ever the undefined work is that the toolbox does.
You should consider purchasing Yair's book on improving MATLAB performance; http://undocumentedmatlab.com/books/matlab-performance

Categorías

Más información sobre Loops and Conditional Statements en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by