Matlab - faster scripts
Matlab is easy to use, but the easiest method might not be the fastest. Fortunately, some of the simpler ways to improve the speed of matlab programs are also amongst the most effective, leading to order-of-magnitude improvements.
Firstly, make sure you're not writing unnecessary code. Each new version of matlab has new functions that might be useful, and functions that have been made faster. R2015b for example made function calls and object-orientated code faster. Consequently there was an average speed-up of 40% with the applications they tested. Remember that some of matlab's commands are scripts and some are built-in functions which are going to be faster than anything you can write. Use the which command to find out whether or not a function is a script (cumsum for example, isn't).
Also make sure you're up to date with matlab's newer features: Some (like cells and structures) might make your code tidier but slower; others (like the newer visualisation routines) may speed up your code considerably.
Then go through this checklist of issues to consider. Some directly affect speed. Others affect memory usage, which in turn affects speed.
JIT (Just-In-Time) Accelerator
Matlab 6.5 introduced the "JIT-Accelerator" which greatly speeds up some scripts with big simple "for" loops. If you have pre-2006 matlabs it might be worth use the profile routine to help you adapt your code to take advantage of it. Newer matlabs don't show JIT information in the profile output, but it's still worth helping the JIT-Accelerator. Not all of the tweaks are obvious - indeed, some of them would nearly halve the speed of the program were it not for the JIT-Accelerator.
R2015b was the first release to use JIT for all non-parallelised code. Whenever Matlab meets new code it now pre-compiles it, making re-runs faster. Consequently, make sure you don't use
clear all when you meant to use
clear - the former not only clears variables but also the pre-compiled code.
Some matlab routines are *.m files, others are compiled into matlab (built-in) and are much faster. Try to use built-ins where possible. Use type functionname to see if a function is a built-in.
There are 2 sorts of M-files - functions and scripts. When you call an M-file function MATLAB parses it and stores it in memory, so that on subsequent calls it runs faster. The difference isn't much, but functions are better than scripts anyway - they make use of their own local variables and accept input arguments. Look up the function command to find out how to write functions.
Matlab has the ability to increase the size of a matrix on demand. If you know the maximum size of a matrix beforehand, it's worth creating the matrix with this size initially rather than making the matrix grow incrementally. Speed-up factors of 500 are possible using this method.
Matlab has 2 ways of storing matrices - full and sparse. Full matrices store their all of their elements in a block of memory; sparse matrices keep a list of the non-zero elements. If matrices aren't dense, using sparse matrices saves memory and increases speed. If you save the following text as spdemo.m you can experiment with using different matrix sizes and densities. For example, spdemo(100,.1) compares multiplication for full and sparse matrices of size 100 by 100 and density .1.
function sp = spdemo(arg1, arg2) % Comparison of sparse vs full matrices if (nargin ~= 2) error('Give order and density'); return end S = sprandn(arg1,arg1,arg2); F = full(S); % Compare speed. t0=cputime; B = S * S; stime=cputime-t0; t0=cputime; C = F * F; ftime=cputime-t0; sprintf('Order %d matrix, density %f: Full=%f, Sparse=%f', arg1, ... arg2, ftime, stime)
Structures of arrays are faster than arrays of structures.
Note that if you're processing a 2D array, it's faster to scan down the columns than along the rows.
The clear command lets memory associated with variables be recycled. Such space get recycled anyway in many circumstances (e.g. the variables created in a function are cleared when the function ends), but you may have to explicitly use clear, especially in long programs. One particular scenario to beware of is the following
for i =1:1000 a=ones(1000*i); % lots more code end
Here a is being recreated in each iteration, but while the a=ones(1000*i) command is being executed there's a moment when the new a has been constructed, but the old one hasn't been destroyed. If both arrays are big this will result in a sudden peak in memory usage. Putting clear a before the a=ones(1000*i) line will solve the problem.
Before you start spending a lot of time on optimising it's useful to find out where the main bottlenecks are. The profile command can do this for you, providing text or graphical output. For example, this is how you could profile spdemo.m
profile on spdemo(100, .1) profile off profile viewer
You'll need to click on the function names displayed by the viewer in order to get detailed information. Within the department one particular diagnostic session led to a speedup of 3000 times (to several hours to several seconds) when it turned out that the same huge .mat file was being loaded on every iteration of a loop.
Matlab scripts can be written using fortran/C-style "for" loops, but to make the most of matlab's abilities you should try whenever possible to treat matrices as a single entity rather than a bundle of elements. A separate document deals with vectorisation tricks
Matlab routines deal with general cases. If your data has a special feature (matrices are symmetrical, for instance) you may be able to implement an algorithm which is tuned to your special case. See Mex files - an example.
It's possible to combine the ease of writing M-files with the speed provided by writing in C or Fortran. Compilers (Mathworks' mcc or the free matcom) convert M-files into compiled C code. Our Signal Processing & Communications group have used mcc successfully. However, mcc isn't free. Also speed improvements depend strongly on the particular application. In some cases, performance improves by more than 200 times, while other files show little or no improvement. Note also that the compiler is rather expensive, and users will need to have a big file installed before the matlab application will work.
Whether or not you use a compiler, it's worth using other optimisation techniques too.
If 1 CPU isn't enough, you could use more. You may have a multi-CPU machine or access to several machines. Note that the current version of matlab uses 1 CPU by default, but you can change that behaviour - see our Matlab parallelisation section.
If you have an CUDA-enabled NVIDIA GPU with compute capability 2.0 or higher, Matlab makes it easy to use the graphics accelerator board to speed matlab up. Many MATLAB built-in functions support
gpuArray input arguments. Whenever any of these functions is called with at least one
gpuArray as an input argument, the function executes on the GPU and generates a
gpuArray as the result. The example on mathwork's Run Built-In Functions on a GPU page is
Ga = rand(1000,'single','gpuArray'); Gfft = fft(Ga); Gb = (real(Gfft) + Ga) * 6; G = gather(Gb);
Other options include
- pMatlab: Parallel Matlab Toolbox
- Parallel Computing Toolbox (Mathworks) (supports CUDA)
- Distributed Computing Server (Mathworks)
- MATLAB plug-in for CUDA (CUDA is a library that used an nVidia board)
- Techniques to Improve Performance (Mathworks)