MEX file running slower than native MATLAB code.

1 visualizzazione (ultimi 30 giorni)
Ubaid Ullah
Ubaid Ullah il 3 Lug 2015
Commentato: Ubaid Ullah il 4 Lug 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 Commenti
James Tursa
James Tursa il 4 Lug 2015
No way to tell unless we see the mex code.
Ubaid Ullah
Ubaid Ullah il 4 Lug 2015
@james I have updated the question with related code. Thanks.

Accedi per commentare.

Risposte (0)

Categorie

Scopri di più su Write C Functions Callable from MATLAB (MEX Files) in Help Center e File Exchange

Prodotti

Community Treasure Hunt

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

Start Hunting!

Translated by