optimization code generation for real-time applications
time limits on generated code
embedded applications might have requirements that limit how long code can run before returning an answer. such requirements can be problematic, because solvers give no time guarantees for optimization. this topic outlines techniques for estimating how long your embedded code will run before returning a result, and describes changes you can make to your code to shorten the time requirement.
for general advice on writing efficient code for code generation, see (matlab coder).
match the target environment
to estimate the execution time of generated code before code generation, set your matlab® environment to match the target environment as closely as possible.
check the clock speeds of your target hardware and your computer. scale your benchmarking results accordingly.
set
maxnumcompthreads
in matlab to 1, because the default lapack and blas libraries generated by matlab coder™ are single-threaded.lastn = maxnumcompthreads(1);
after you finish benchmarking, reset the
maxnumcompthreads
value:n = maxnumcompthreads(lastn); % alternatively, % n = maxnumcompthreads('automatic');
note
if your target hardware has multiple cores and you use custom multithreaded lapack and blas libraries, then set
maxnumcompthreads
to the number of threads on the target hardware. see (matlab coder).if you have an embedded coder® license, see these topics for details on reliable ways to evaluate the resulting performance of your embedded code: (embedded coder), (embedded coder), (embedded coder), and (embedded coder).
set coder configuration
to set the configuration for code generation, call
coder.config
.
cfg = coder.config('mex');
to save time in the generated code, turn off integrity checks and checks for integer saturation. solvers do not rely on these checks to function properly, assuming that the objective function and nonlinear constraint function do not require them. for details, see (matlab coder).
cfg.integritychecks = false; cfg.saturateonintegeroverflow = false;
typically, generated code runs faster when using static memory allocation, although this allocation can increase the amount of generated code. also, some hardware does not support dynamic memory allocation. to use static memory allocation, specify this setting.
cfg.dynamicmemoryallocation = 'off';
you can improve the performance of your code by selecting different types of blas, the underlying linear algebra subprograms. to learn how to set the blas for your generated code, see (matlab coder). if you want the embedded application to run in parallel, you must supply blas or lapack libraries that support parallel computation on your system. similarly, when you have parallel hardware, you can improve the performance of your code by setting custom lapack calls. see (matlab coder).
benchmark the solver
run your mex generated code in a loop of 1000 evaluations using a set of input parameters that is typical of your application. find both the total time and the maximum of the evaluation times. try the parameters that you think might cause the solver to take too long, and test them and other parameters. if the mex application returns satisfactory results in reasonable time frames, then you can expect that the deployed application will do the same.
set initial point
one of the most important factors affecting both runtime and solution quality is
the initial point for the optimization x0
. when parameters change
slowly between solver calls, the solution from the previous call is typically a good
starting point for the next call. see , which also
shows how a jump in the solution time can occur because the solution switches basins of attraction.
if your optimization problem does not have parameters changing slowly, and includes only a few control variables, then trying to estimate a response from previous solutions can be worthwhile. construct a model of the solution as a function of the parameters, either as a quadratic in the parameters or as a low-dimensional interpolation, and use the predicted solution point as a starting point for the solver.
set options appropriately
you can sometimes speed a solution by adjusting parameters. if you set the
maxiterations
option to allow only a few iterations, then the
solver stops quickly. for example, if the solver is fmincon
,
enter this code.
opts = optimoptions('fmincon','algorithm','sqp','maxiterations',50); [x,fval,exitflag] = fmincon(fun,x0,a,b,aeq,beq,lb,ub,nonlcon,options)
however, the result can be far from an optimum. ensure that an inaccurate result
does not overly affect your system. set maxiterations
as large as
possible while still meeting your time constraint. you can estimate this value by
measuring how long an iteration takes, or by measuring how long a function
evaluation takes, and then either setting the
maxfunctionevaluations
option or the
maxiterations
option. for an example, see code generation for optimization basics.
for further suggestions on settings that can speed the solver, see . note that some suggestions in this topic do not apply because of limitations in code generation. see or .
global minimum
you might want a global minimum, not just a local minimum, as a solution. searching for a global minimum can take a great deal of time, and is not guaranteed to work. for suggestions, see searching for a smaller minimum.
see also
| codegen
(matlab coder) | |