우선이 질문을 자세히 살펴보면 분명해 지므로이 질문을 중복으로 표시하지 말 것을 요청합니다.
Orthogonal Matching Pursuit 알고리즘을 구현하려고합니다. 이를 위해 아래와 같이 크기가 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 = 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에서 사용되는 솔루션보다 훨씬 느리다는 사실을 알게되었습니다. 원인을 알기 위해 인터넷에서 많이 검색했고 다음과 같은 흥미로운 사실을 발견했습니다.
Matlab : 루프에서 동일한 mex 함수를 반복적으로 호출하면 오버 헤드가 너무 많이 발생합니까?
mexCallMATLAB을 사용하는 Matlab mex-file은 해당 m-file보다 거의 300 배 느립니다.
이 링크는 오버 헤드가 많지 않아야 함을 시사하며 심볼 테이블 등을로드하는 데 시간이 필요하기 때문에 항상 첫 번째 호출을위한 것입니다. -그러나 이와는 반대로 코드에 많은 오버 헤드가 발생한다는 것을 알았습니다.
또한 인수의 수가 계산 시간에 영향을 미칠 수 있지만 인수의 크기는 중요하지 않지만 다시 최소한이라는 것을 발견했습니다. 링크 중 하나는 또한 동적으로 할당 된 메모리를 해제해야한다고 제안하지만 (matlab 자체에 의해 할당 된 것과는 별개로) 이러한 종류의 할당도 없습니다.
그래서 친절하게 이유가 무엇인지 알려주십시오.
왜 MEX에 엄청난 시간이 걸리나요?
그것에 대한 해결책은 무엇일까요?
귀하의 도움에 감사드립니다.
여기에서 다양한 파일을 찾을 수 있습니다.
Matlab은 행렬의 내적을 계산하기 위해 고도로 최적화 된 코드를 가지고 있습니다.
방금 내적을 계산하기 위해 중첩 된 for 루프를 작성 했으므로이 Mex 코드를 matlab의 "비슷한 중첩 for 루프"와 비교 한 다음 MEX 코드가 더 빠른지 matlab,
사실 matlab은 중첩 된 for 루프를 사용하여 행렬의 내적을 계산하지 않습니다.
MATLAB 문서에서 :
MEX-Files에는 여러 응용 프로그램이 있습니다.
기존의 대규모 c / c ++ 및 FORTRAN 프로그램을 MATLAB 함수로 다시 쓰지 않고 MATLAB에서 호출
성능에 중요한 루틴을 C / C ++ 구현으로 대체
MEX 파일은 모든 응용 프로그램에 적합하지 않습니다. MATLAB은 C 또는 C ++와 같은 컴파일 된 언어에서 시간이 많이 걸리는 저수준 프로그래밍을 제거하는 전문성을 갖춘 고 생산성 환경입니다. 일반적으로 MATLAB에서 프로그래밍을 수행하십시오. 응용 프로그램에서 요구하지 않는 한 MEX 파일을 사용하지 마십시오.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다