Mex-файл Matlab с mexCallMATLAB почти в 300 раз медленнее соответствующего m-файла
Я начал реализовывать несколько m-файлов в C ++, чтобы сократить время выполнения. M-файлы создают n-мерные точки и оценивают значения функций в этих точках. Функции определяются пользователем и передаются в m-файлы и mex-файлы в качестве дескрипторов функций. Mex-файлы используют mexCallMATLAB с feval для поиска значений функций.
Я построил приведенный ниже пример, где дескриптор функции fn, созданный в командной строке Matlab, передается процедурам matlabcallingmatlab.m и mexcallingmatlab.cpp. В недавно открытом Matlab mexcallingmatlab оценивает эту функцию 200000 за 241,5 секунды, в то время как matlabcallingmatlab оценивает ее за 0,81522 секунды, следовательно, при реализации mex замедление в 296 раз. Эти времена являются результатами второго запуска, так как первый запуск кажется больше, вероятно, из-за некоторых накладных расходов, связанных с первой загрузкой программы и т. Д.
Я потратил много дней на поиск этой проблемы в Интернете и попробовал несколько предложений по ней. Я пробовал разные флаги компиляции mex для оптимизации mex, но по производительности почти не было различий. В предыдущем сообщении в Stackoverflow говорилось, что обновление Matlab было решением, но я использую, вероятно, последнюю версию MATLAB Version: 8.1.0.604 (R2013a) в Mac OS X Версия: 10.8.4. Я скомпилировал mex файл с и без -флаг largeArrayDims, но это нене имеет никакого значения либо. Некоторые предположили, что содержимое дескриптора функции может быть непосредственно закодировано в файле cpp, но это невозможно, поскольку я хотел бы предоставить этот код любому пользователю с любым типом функции с векторным вводом и выводом действительного числа.
Насколько я выяснил, для использования дескриптора функции mex-файлы должны проходить через функцию feval, тогда как m-файлы могут напрямую вызывать дескрипторы функций при условии, что версия Matlab новее, чем некоторая версия.
Любая помощь будет принята с благодарностью.
простой дескриптор функции, созданный в командной строке Matlab:
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
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( 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] );
}
}
Компиляция mex файла:
>> mex -v -largeArrayDims mexcallingmatlab.cpp