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

Ответы на вопрос(3)

Ваш ответ на вопрос