MEX file running slower than native MATLAB code.

1 vue (au cours des 30 derniers jours)
Ubaid Ullah
Ubaid Ullah le 3 Juil 2015
Commenté : Ubaid Ullah le 4 Juil 2015
Hello
I have the following code:
spmd
sum_gammaXmom = g{1}*gamma(1);
for mm = 2:d.mom
sum_gammaXmom = sum_gammaXmom + g{mm}*gamma(mm);
end
w_exp_sum_gammaXmom = bsxfun(@times,exp(sum_gammaXmom),d.scale);
denom = sum(w_exp_sum_gammaXmom,2);
weight = bsxfun(@rdivide,w_exp_sum_gammaXmom,denom);
gtilde = zeros(length(denom),d.mom);
for mm = 1:d.mom
gtilde(:,mm) = sum(g{mm}.*weight,2);
end
end
The variable 'g' is of composite type and has data for different worker labs, where 'g' variable contains a cell array of double matrices. To speed up the execution, I converted the two loops into MEX files and compiled with gcc compiler. Strangely, my MEX file runs slower than MATLAB native code written above. Is this because both the first and second loops take in 'g' which is a cell array, rather than a 3D matrix?
The wrapper with MEX code is as follows:
spmd
sum_gammaXmom = give_gtilde_spmd_loop1(g, d.mom, gamma);
w_exp_sum_gammaXmom = bsxfun(@times,exp(sum_gammaXmom),d.scale);
denom = sum(w_exp_sum_gammaXmom,2);
weight = bsxfun(@rdivide,w_exp_sum_gammaXmom,denom);
gtilde = give_gtilde_spmd_loop2(g, d.mom, weight);
end
give_tilde_spmd_loop1.c is as follows:
#include <math.h>
#include <matrix.h>
#include <mex.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
const mwSize *dims;
const mxArray *cell;
const mxArray *cellArray;
double *pr;
double *gamma;
double *sum_gammaXmom;
int mom, cellSize, nnz;
bool issparse;
mwIndex i, j, k, count, jcell,*ir, *jc;
mwSize ncol, nrow;
cell = prhs[0];
dims = mxGetDimensions(prhs[0]);
mom = (int)mxGetScalar(prhs[1]);
gamma = mxGetPr(prhs[2]);
if(mom>dims[0]) mexErrMsgTxt("d.mom variable exceeds g cell array size.");
jcell = 0;
cellArray = mxGetCell(prhs[0], jcell);
cellSize = mxGetNumberOfElements(prhs[0]);
nrow = mxGetM(cellArray);
ncol = mxGetN(cellArray);
pr = mxGetPr(cellArray);
plhs[0] = mxCreateDoubleMatrix(nrow, ncol, mxREAL);
sum_gammaXmom = mxGetPr(plhs[0]);
count = 0;
for(j=0;j<(ncol*nrow);j++) sum_gammaXmom[j] = 0;
for (jcell=0; jcell<mom; jcell++) {
cellArray = mxGetCell(prhs[0], jcell);
issparse = mxIsSparse(cellArray);
if(issparse) {
ir = mxGetIr(cellArray);
pr = mxGetPr(cellArray);
jc = mxGetJc(cellArray);
for(j=0;j<ncol;j++) {
nnz = jc[j+1] - jc[j];
for(k=0;k<nnz;k++) {
sum_gammaXmom[ir[jc[j]+k]+j*nrow] += pr[jc[j]+k]*gamma[jcell];
}
}
}
else{
pr = mxGetPr(cellArray);
for(j=0;j<(nrow*ncol);j++) {
sum_gammaXmom[j] += pr[j]*gamma[jcell];
}
}
}
}
give_tilde_spmd_loop2.c is as follows:
#include <math.h>
#include <matrix.h>
#include <mex.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
const mwSize *dims;
const mxArray *cell;
const mxArray *cellArray;
double *pr;
double *weight;
double *sum_gammaXmom;
int mom, cellSize, nnz;
bool issparse;
mwIndex i, j, k, count, jcell,*ir, *jc;
mwSize ncol, nrow;
cell = prhs[0];
dims = mxGetDimensions(prhs[0]);
mom = (int)mxGetScalar(prhs[1]);
weight = mxGetPr(prhs[2]);
if(mom>dims[0]) mexErrMsgTxt("d.mom variable exceeds g cell array size.");
jcell = 0;
cellArray = mxGetCell(prhs[0], jcell);
cellSize = mxGetNumberOfElements(prhs[0]);
nrow = mxGetM(cellArray);
ncol = mxGetN(cellArray);
pr = mxGetPr(cellArray);
plhs[0] = mxCreateDoubleMatrix(nrow, mom, mxREAL);
sum_gammaXmom = mxGetPr(plhs[0]);
count = 0;
for(j=0;j<(mom*nrow);j++) sum_gammaXmom[j] = 0;
for (jcell=0; jcell<mom; jcell++) {
cellArray = mxGetCell(prhs[0], jcell);
issparse = mxIsSparse(cellArray);
if(issparse) {
ir = mxGetIr(cellArray);
pr = mxGetPr(cellArray);
jc = mxGetJc(cellArray);
for(j=0;j<ncol;j++) {
nnz = jc[j+1] - jc[j];
for(k=0;k<nnz;k++) {
sum_gammaXmom[ir[jc[j]+k]+jcell*nrow] += pr[jc[j]+k]*weight[ir[jc[j]+k]+j*nrow];
}
}
}
else{
pr = mxGetPr(cellArray);
for(i=0;i<nrow;i++) {
for(j=0;j<ncol;j++){
sum_gammaXmom[i+jcell*nrow] += pr[i+j*nrow]*weight[i+j*nrow];
}
}
}
}
}
  2 commentaires
James Tursa
James Tursa le 4 Juil 2015
No way to tell unless we see the mex code.
Ubaid Ullah
Ubaid Ullah le 4 Juil 2015
@james I have updated the question with related code. Thanks.

Connectez-vous pour commenter.

Réponses (0)

Catégories

En savoir plus sur Write C Functions Callable from MATLAB (MEX Files) dans Help Center et File Exchange

Produits

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by