From the Lab
MEX-Functions for MATLAB Written in C
Bernard Llanos — June 20, 2013 - 10:48am
Introduction
The MATLAB language is ideal for writing prototype programs very quickly, as MATLAB provides a large number of built-in functions and it is possible to run code fragments without embedding them in a full program with a "main" function, header files, etc. Unfortunately, MATLAB programs are interpreted as opposed to compiled and run more slowly than compiled C programs, for example.
On the other hand, it is possible to take advantage of both the speed of C and the ease of use of MATLAB by writing MEX-functions in C. I decided to use this approach in order to obtain a faster cumulative range geodesic filtering program than the MATLAB code version which I had written earlier.
Learning C/MEX programming is a little more difficult than learning MATLAB programming, as MATLAB's help files on this topic are fewer and more concise than those on the MATLAB programming language. Nevertheless, MATLAB's help system still provides many sample programs which are useful for learning specific techniques, and there is a good overview page called "MEX-Files Call C/C++ and Fortran Programs". I also made use of a tutorial by Pascal Getreuer, available at http://www.getreuer.info/tutorials
A Few Tips on C MEX-Functions
- It may be necessary to find a compiler that will produce executable files which are compatible with MATLAB. MATLAB will recognize a few different compilers, which can be called directly from MATLAB's command line to compile MEX-functions. They are listed at http://www.mathworks.com/support/compilers/R2013a/index.html The 32-bit version of MATLAB for Windows actually comes with the "lcc-win32 v2.4.1" compiler, which I used. However, it is also possible (though more difficult) to compile MEX-functions outside of MATLAB. MATLAB cannot be used to debug MEX-functions, although MEX-functions can output text and values to MATLAB's command window using the "mexPrintf" function to help with debugging.
-
In attempting to write an efficient C MEX-function, I followed many of the tips given in the article "Writing Efficient C and C Code Optimization" by Koushik Ghosh (26 Feb 2004): http://www.codeproject.com/Articles/6154/Writing-Efficient-C-and-C-Code-Optimization
-
In the examples provided through MATLAB's help system, a significant amount of code is devoted to validating input arguments. Error checking may be time-consuming to implement. However, it is quite easy to carelessly copy and paste MATLAB code which calls a MEX-function and end up passing invalid parameters. Consequently, I have found that having my MEX-function catch these silly mistakes is much nicer than not having any error-checking code and crash MATLAB.
-
When I first used MATLAB's dynamic memory allocations in my MEX program, I ended up crashing MATLAB due to a "memory segmentation violation". It took a few web searches to find out that this error usually arises when the program tries to access memory locations beyond the edges of arrays. In my case, I had usually generated incorrect array indices (e.g. I was looking for pixels outside of an image) or had allocated insufficient memory for an array (e.g. I calculated the memory required for an array of type 'double' as though its elements were of type 'int').
-
Remember to use the "mwSize" and "mwIndex" types to ensure compatibility with the 64-bit API. Refer to http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html
Results
The C/MEX version of the cumulative range geodesic filter runs around 200 times faster than the MATLAB code version. It is sufficiently fast to be used for future experiments.
Below are some plots of the time taken to filter uniformly-distributed random data. The 2D plots contain the same data as the 3D plots, but they make trends in the data easier to see.