O arquivo mex do Matlab com mexCallMATLAB é quase 300 vezes mais lento que o arquivo m correspondente

Comecei a implementar alguns arquivos m em C ++ para reduzir os tempos de execução. Os arquivos-m produzem pontos n-dimensionais e avaliam os valores das funções nesses pontos. As funções são definidas pelo usuário e são passadas para arquivos-m e arquivos-mex como identificadores de função. Os arquivos mex usam mexCallMATLAB com feval para encontrar valores de função.

Eu construí o exemplo abaixo, onde um manipulador de função fn construído na linha de comando do Matlab é passado para as rotinas matlabcallingmatlab.m e mexcallingmatlab.cpp. Com um Matlab recém-aberto, o mexcallingmatlab avalia essa função 200000 em 241,5 segundos, enquanto o matlabcallingmatlab a avalia em 0,81522 segundo, portanto, uma desaceleração de 296 vezes com a implementação mex. Esses tempos são os resultados da segunda execução, já que as primeiras corridas parecem maiores, provavelmente devido a alguma sobrecarga associada ao carregamento pela primeira vez do programa, etc.

Passei muitos dias pesquisando on-line sobre esse problema e tentei algumas sugestões. Eu tentei mex diferentes bandeiras de compilação para otimizar o mex, mas quase não houve diferença no desempenho. Um post anterior no Stackoverflow afirmou que atualizar o Matlab era a solução, mas estou usando provavelmente a versão mais recente do MATLAB: 8.1.0.604 (R2013a) no Mac OS X Versão: 10.8.4. Eu compilei o arquivo mex com e sem sinalizador -largeArrayDims, mas isso também não fez diferença alguma. Alguns sugeriram que o conteúdo do identificador de funções poderia ser codificado diretamente no arquivo cpp, mas isso é impossível, pois eu gostaria de fornecer esse código para qualquer usuário com qualquer tipo de função com uma entrada de vetor e saída de número real.

Até onde eu descobri, os arquivos mex precisam passar pela função feval para usar um identificador de função, enquanto os arquivos m podem chamar diretamente identificadores de função desde que a versão do Matlab seja mais recente que alguma versão.

Qualquer ajuda seria muito apreciada.

manipulador de função simples criado na linha de comando do 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 <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] );
    }
}

Compilação do arquivo mex:

>> mex -v -largeArrayDims mexcallingmatlab.cpp

questionAnswers(3)

yourAnswerToTheQuestion