首先,这是一个请求,不要将这个问题标记为重复,因为一旦详细研究它就会清楚。为什么MEX代码比matlab代码慢得多?
我正在尝试实现正交匹配追踪算法。为此,我需要找到尺寸的两个矩阵的点积如下图所示
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
144 * 14596和144 * 1,但我现在面临的问题是,它需要大量的时间(如看到探查器报告)在MATLAB中使用以下代码找出点积。
inner_product = dictionary'* 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走的时候大量?
什么可以解决它?
您的帮助真的很感激。
各种文件可以在这里找到:
它几乎不可能为你写点产品比MATLAB的一个更快的代码。你说它的速度很慢,是因为单次通话很慢,还是因为你说了很多次,而且总数很大?此外,mex文件速度很快,但在创建和传递变量时可能会听到 –
我认为您还没有完全阅读该文章,并且您的答案尚不清楚。 – Navdeep
你应该专注于使你的MATLAB代码更快,而不是写MEX代码。 MATLAB中的矩阵乘法和点乘积要比你自己写这个要快得多。我可以在你的MATLAB代码中看到几个可以进行矢量化的点。 – rayryeng