views:

1620

answers:

12

I have a lot of nice MATLAB code that runs too slowly and would be a pain to write over in C. The MATLAB compiler for C does not seem to help much, if at all. Should it be speeding execution up more? Am I screwed?

+17  A: 

In my experience slow MATLAB code usually comes from not vectorizing your code (i.e., writing for-loops instead of just multiplying arrays (simple example)).

If you are doing file I/O look out for reading data in one piece at a time. Look in the help files for the vectorized version of fscanf.

Don't forget that MATLAB includes a profiler, too!

dwj
A: 

By Matlab compiler you probably mean the command mcc, which does speed the code a little bit by circumventing Matlab interpreter. What would speed the MAtlab code significantly (by a factor of 50-200) is use of actual C code compiled by the mex command.

+9  A: 

I'll echo what dwj said: if your MATLAB code is slow, this is probably because it is not sufficiently vectorized. If you're doing explicit loops when you could be doing operations on whole arrays, that's the culprit.

This applies equally to all array-oriented dynamic languages: Perl Data Language, Numeric Python, MATLAB/Octave, etc. It's even true to some extent in compiled C and FORTRAN compiled code: specially-designed vectorization libraries generally use carefully hand-coded inner loops and SIMD instructions (e.g. MMX, SSE, AltiVec).

Dan
A: 

As others has noted, slow Matlab code is often the result of insufficient vectorization.

However, sometimes even perfectly vectorized code is slow. Then, you have several more options:

  1. See if there are any libraries / toolboxes you can use. These were usually written to be very optimized.
  2. Profile your code, find the tight spots and rewrite those in plain C. Connecting C code (as DLLs for instance) to Matlab is easy and is covered in the documentation.
Eli Bendersky
+8  A: 

If you are using the MATLAB complier (on a recent version of MATLAB) then you will almost certainly not see any speedups at all. This is because all the compiler actually does is give you a way of packaging up your code so that it can be distributed to people who don't have MATLAB. It doesn't convert it to anything faster (such as machine code or C) - it merely wraps it in C so you can call it.

It does this by getting your code to run on the MATLAB Compiler Runtime (MCR) which is essentially the MATLAB computational kernel - your code is still being interpreted. Thanks to the penalty incurred by having to invoke the MCR you may find that compiled code runs more slowly than if you simply ran it on MATLAB.

Put another way - you might say that the compiler doesn't actually compile - in the traditional sense of the word at least.

Older versions of the compiler worked differently and speedups could occur in certain situations. For Mathwork's take on this go to

http://www.mathworks.com/support/solutions/data/1-1ARNS.html

MikeCroucher
A: 

mcc won't speed up your code at all--it's not really a compiler.

Before you give up, you need to run the profiler and figure out where all your time is going (Tools->Open Profiler). Also, judicious use of "tic" and "toc" can help. Don't optimize your code until you know where the time is going (don't try to guess).

Keep in mind that in matlab:

  • bit-level operations are really slow
  • file I/O is slow
  • loops are generally slow, but vectorizing is fast (if you don't know the vector syntax, learn it)
  • core operations are really fast (e.g. matrix multiply, fft)
  • if you think you can do something faster in C/Fortran/etc, you can write a MEX file
  • there are commercial solutions to convert matlab to C (google "matlab to c") and they work
+4  A: 

First, I second all the above comments about profiling and vectorizing.

For a historical perspective...

Older version of Matlab allowed the user to convert m files to mex functions by pre-parsing the m code and converting it to a set of matlab library calls. These calls have all the error checking that the interpreter did, but old versions of the interpreter and/or online parser were slow, so compiling the m file would sometimes help. Usually it helped when you had loops because Matlab was smart enough to inline some of that in C. If you have one of those versions of Matlab, you can try telling the mex script to save the .c file and you can see exactly what it's doing.

In more recent version (probably 2006a and later, but I don't remember), Mathworks started using a just-in-time compiler for the interpreter. In effect, this JIT compiler automatically compiles all mex functions, so explicitly doing it offline doesn't help at all. In each version since then, they've also put a lot of effort into making the interpreter much faster. I believe that newer versions of Matlab don't even let you automatically compile m files to mex files because it doesn't make sense any more.

Mr Fooz
+1  A: 

Have you tried profiling your code? You don't need to vectorize ALL your code, just the functions that dominate running time. The MATLAB profiler will give you some hints on where your code is spending the most time.

There are many other things you you should read up on the Tips For Improving Performance section in the MathWorks manual.

+1  A: 

You could port your code to "Embedded Matlab" and then use the Realtime-Workshop to translate it to C.

Embedded Matlab is a subset of Matlab. It does not support Cell-Arrays, Graphics, Marices of dynamic size, or some Matrix addressing modes. It may take considerable effort to port to Embedded Matlab.

Realtime-Workshop is at the core of the Code Generation Products. It spits out generic C, or can optimize for a range of embedded Platforms. Most interresting to you is perhaps the xPC-Target, which treats general purpose hardware as embedded target.

edgar.holleis
+1  A: 

The MATLAB compiler wraps up your m-code and dispatches it to a MATLAB runtime. So, the performance you see in MATLAB should be the performance you see with the compiler.

Per the other answers, vectorizing your code is helpful. But, the MATLAB JIT is pretty good these days and lots of things perform roughly as well vectorized or not. That'a not to say there aren't performance benefits to be gained from vectorization, it's just not the magic bullet it once was. The only way to really tell is to use the profiler to find out where your code is seeing bottlenecks. Often times there are some places where you can do local refactoring to really improve the performance of your code.

There are a couple of other hardware approaches you can take on performance. First, much of the linear algebra subsystem is multithreaded. You may want to make sure you have enabled that in your preferences if you are working on a multi-core or multi-processor platform. Second, you may be able to use the parallel computing toolbox to take more advantage of multiple processors. Finally, if you are a Simulink user, you may be able to use emlmex to compile m-code into c. This is particularly effective for fixed point work.

Todd
A: 

I would vote for profiling + then look at what are the bottlenecks.

If the bottleneck is matrix math, you're probably not going to do any better... EXCEPT one big gotcha is array allocation. e.g. if you have a loop:

s = [];
for i = 1:50000
  s(i) = 3;
end

This has to keep resizing the array; it's much faster to presize the array (start with zeros or NaN) & fill it from there:

s = zeros(50000,1);
for i = 1:50000
  s(i) = 3;
end

If the bottleneck is repeated executions of a lot of function calls, that's a tough one.

If the bottleneck is stuff that MATLAB doesn't do quickly (certain types of parsing, XML, stuff like that) then I would use Java since MATLAB already runs on a JVM and it interfaces really easily to arbitrary JAR files. I looked at interfacing with C/C++ and it's REALLY ugly. Microsoft COM is ok (on Windows only) but after learning Java I don't think I'll ever go back to that.

Jason S
A: 

Many "Writing fast Matlab code" posts are on:

http://www.advancedmcode.org/writing-fast-matlab-code-introduction.html

They may help you improve your code performances.

Luigi Giaccari