I started embedding a few m files in C ++ to shorten the execution time. M files produce n-dimensional points and evaluate the values โโof the functions at these points. Functions are user-defined, and they are transferred to m files and mex files as functions. Mex files use mexCallMATLAB with feval to search for function values.
I built the example below, where the fn function descriptor built on the Matlab command line is passed to matlabcallingmatlab.m and mexcallingmatlab.cpp procedures. Thanks to the recently opened Matlab, mexcallingmatlab evaluates this feature to 200,000 in 241.5 seconds, while matlabcallingmatlab evaluates it at 0.81522 seconds, so it slows down 296 times using mex. These times are the result of the second runs, as the first runs are apparently longer, probably due to some associated with the service data of the first program load, etc.
For many days I searched the Internet for this problem and tried some suggestions on it. I tried various mex compiling flags to optimize mex, but there was practically no difference in performance. A previous post on Stackoverflow stated that updating Matlab was a solution, but I'm probably using the latest version of MATLAB Version: 8.1.0.604 (R2013a) on Mac OS X Version: 10.8.4. I compiled the mex file with and without flag -largeArrayDims, but that didn't matter either. Some have suggested that the contents of a function descriptor can be directly encoded in a cpp file, but this is not possible because I would like to provide this code to any user with any type of function with vector input and a valid number.
As far as I know, mex files must go through the feval function to use the function descriptor, while m files can directly call function descriptors, provided that the version of Matlab is newer than any version.
Any help would be greatly appreciated.
simple function descriptor created on the matlab command line :
fn = @(x) x'*x
matlabcallingmatlab.m :
function matlabcallingmatlab( fn ) x = zeros(2,1); for i = 0 : 199999 x(2) = i; f = fn( x ); end
mexcallingmatlab.cpp
#include "mex.h" #include <cstring> void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { mxArray *lhs[1], *rhs[2]; //parameters to be passed to feval double f, *xptr, x[] = {0.0, 0.0}; // x: input to f and f=f(x) int n = 2, nbytes = n * sizeof(double); // n: dimension of input x to f // prhs[0] is the function handle as first argument to feval rhs[0] = const_cast<mxArray *>( prhs[0] ); // rhs[1] contains input x to the function rhs[1] = mxCreateDoubleMatrix( n, 1, mxREAL); xptr = mxGetPr( rhs[1] ); for (int i = 0; i < 200000; ++i) { x[1] = double(i); // change input memcpy( xptr, x, nbytes ); // now rhs[1] has new x mexCallMATLAB(1, lhs, 2, rhs, "feval"); f = *mxGetPr( lhs[0] ); } }
Compiling the mex file :
>> mex -v -largeArrayDims mexcallingmatlab.cpp