为什么MEX代码比matlab代码慢得多?

时间:2017-03-16 11:54:15

标签: matlab visual-studio-2012 mex computation

首先,请求不要将此问题标记为重复,因为一旦详细研究它就会很清楚。

我正在尝试实现正交匹配追踪算法。为此,我需要找到两个尺寸为144 * 14596和144 * 1的矩阵的点积,如下所示

        clc,clear;

        load('E');
        load('R');
        load('P');


        sparse=zeros(14596,2209);

            dictionary=tem2;

            atoms=zeros(size(dictionary,1),size(dictionary,2));
            coefs=zeros(size(dictionary,2),1);
        tic
            %Normalize the dictionary 
            for index=1:size(dictionary,2)
               dictionary(:,index)=dictionary(:,index)./norm(dictionary(:,index)); 
            end
            D=dictionary;

      /*  NOTE: I tried for ii=1:5 to check the difference in computational time*/

         for ii=1:2209

            r=tem4(:,ii);
            dictionary=D;
            index=[];
            count=0;
            t=5;
            while(t>1e-15 && count~=144)
    /***************Problem lies here**************/
        % inner_product=dictionary'*r; %Dot Product (Should be slow but is fast)
        inner_product=dotProduct(dictionary',r); %(Should be fast but is very slow)
/****************************************************/
                [m,ind]=max(abs(inner_product));

                index=[index ind];
                atoms(:,ind)=dictionary(:,ind); %Select atom which has maximum inner product
                dictionary(:,ind)=0;
                at=atoms(:,index);
                x=(at'*at)\(at'*r);
                coefs(index)=x;
                r=r-at*x;
                t=norm(r);
                count=count+1;
            end
                sparse(:,ii)=coefs;

         end

        sig=D*sparse;
        final=uint8((repmat((((max(tem4))-min(tem4))./((max(sig)-min(sig)))),size(tem4,1),1).*(sig-repmat(min(sig),size(tem4,1),1)))+repmat(min(tem4),size(tem4,1),1));  

        toc

但我面临的问题是,在MATLAB中使用以下代码查找点积需要花费大量时间(如剖析器报告中所示)。

  

inner_product =字典' * R;

为了减少计算时间,我编写了如下所示的MEX代码来找出点积:

/***********************************************************************
 *Program to create a MEX-file to find the dot product of matrices     *
 *Created by: Navdeep Singh                                            * 
 *@Copyright Reserved                                                  * 
 ***********************************************************************/

#include "mex.h"

void dot_prod(double *m1,double *m2, double *t,size_t M,size_t N, size_t M2,size_t N2 )
{   
    int i,j,k;
    double s;

    for(i=0;i<M;i++)
    {   for(k=0;k<N2;k++)
        {   s=0;
            for(j=0;j<N;j++)
            {   s=s+*((m1+i)+(M*j))*(*(m2+(j+M2*k)));
            }
            *((t+i)+(M*k))=s;
        }
    }
}  

void mexFunction(int nlhs,mxArray *plhs[],int nrhs, const mxArray *prhs[])
{   double *mat1,*mat2,*out;
    size_t rows_mat1,cols_mat1,rows_mat2,cols_mat2;
    mat1=mxGetPr(prhs[0]);
    mat2=mxGetPr(prhs[1]);
    rows_mat1=mxGetM(prhs[0]);
    cols_mat1=mxGetN(prhs[0]);
    rows_mat2=mxGetM(prhs[1]);
    cols_mat2=mxGetN(prhs[1]);
    plhs[0]=mxCreateDoubleMatrix(rows_mat1,cols_mat2,mxREAL);
    out=mxGetPr(plhs[0]);
    dot_prod(mat1,mat2,out,rows_mat1,cols_mat1,rows_mat2,cols_mat2);

}

但令我惊讶的是,我发现MEX解决方案比MATLAB中使用的解决方案慢得多,这违背了MEX的最终目的。要知道我在互联网上搜索了很多的原因并找到了一些有趣的事实,例如:

Matlab: Does calling the same mex function repeatedly from a loop incur too much overhead?

Matlab mex-file with mexCallMATLAB is almost 300 times slower than the corresponding m-file

这些链接表明开销不应该太大,如果有一些,它总是第一次调用,因为加载符号表等需要时间。 - 但与此相反,我发现我的代码中会产生很多开销。

此外,我发现参数的大小并不重要,尽管参数的数量会影响计算时间,但它又是最小的。其中一个链接还表明应该释放动态分配的内存(除了由matlab本身分配的内存),但我也没有任何这样的分配。

请让我知道背后的原因是什么

为什么MEX需要花费大量时间?

可以解决哪些问题?

非常感谢您的帮助。

可在此处找到各种文件:

dictionary.m

dotProduct.c

Report MEX

E.mat

R.mat

P.mat

1 个答案:

答案 0 :(得分:3)

Matlab具有高度优化的代码来计算矩阵的点积,

你刚刚编写了一个嵌套的for循环来计算点积,所以你可以将这个Mex代码与&#34;类似的嵌套for循环&#34;进行比较。然后在matlab中决定MEX代码是更快还是matlab,

实际上matlab不使用嵌套for循环来计算矩阵的点积,

来自MATLAB doc:

  

MEX-Files有几个应用程序:

     
      
  • 从MATLAB调用大型预先存在的c / c ++和FORTRAN程序,而不将它们重写为MATLAB函数

  •   
  • 用c / c ++实现取代性能关键的例程

  •   
     

MEX文件并不适合所有应用程序。 MATLAB是一个高效的环境,其特点是消除了C或C ++等编译语言中耗时,低级的编程。通常,在MATLAB中进行编程。除非您的应用程序需要,否则请勿使用MEX文件。

EXAMPLE1