linux matlab版本中OpenMP的使用
需要重点注意linux和window mex编译的参数不一样!
这里参考edgeBOX论文提供代码的参数选择
Next, please compile mex code from within Matlab (note: win64/linux64 binaries included):
mex private/edgesDetectMex.cpp -outdir private [OMPPARAMS]
mex private/edgesNmsMex.cpp -outdir private [OMPPARAMS]
mex private/spDetectMex.cpp -outdir private [OMPPARAMS]
mex private/edgeBoxesMex.cpp -outdir private
Here [OMPPARAMS] are parameters for OpenMP and are OS and compiler dependent.
Windows: [OMPPARAMS] = '-DUSEOMP' 'OPTIMFLAGS="$OPTIMFLAGS' '/openmp"'
Linux V1: [OMPPARAMS] = '-DUSEOMP' CFLAGS="\$CFLAGS -fopenmp" LDFLAGS="\$LDFLAGS -fopenmp"
Linux V2:[OMPPARAMS] = '-DUSEOMP' CXXFLAGS="\$CXXFLAGS -fopenmp" LDFLAGS="\$LDFLAGS -fopenmp"
To compile without OpenMP simply omit [OMPPARAMS]; note that code will be single threaded in this case.
对于windows matlab2014b版本,同样可以使用一下参数进行编译
mex euc_nn_mex_K.cpp COMPFLAGS="/openmp $COMPFLAGS"
但是,在linux上不能使用该参数,否则即使编译通过,线程数也只为1。
在不明确定义线程数的情况下,系统运行可以达到最大线程数,即系统核心数 CPU数目单个CPU核心数*。
另外还可以参考
mex euc_nn_mex.cc CXXFLAGS="\$CXXFLAGS -fopenmp -Wall"
LDFLAGS="\$LDFLAGS -fopenmp";
mex kmeans_iter_mex.cc CXXFLAGS="\$CXXFLAGS -Wall"
代码参考
#include <assert.h>
#include <math.h>
#include "mex.h"
#include <sys/time.h>
void mexFunction(int nlhs, mxArray* plhs[],
int nrhs, const mxArray* prhs[]) {
if (nrhs != 2)
mexErrMsgTxt("There should be two input arguments.");
if (nlhs != 2 && nlhs != 1)
mexErrMsgTxt("There should be one or two output arguments.");
int p = mxGetM(prhs[0]);
int n = mxGetN(prhs[0]);
int nq = mxGetN(prhs[1]);
if (mxGetM(prhs[1]) != (unsigned int)p)
mexErrMsgTxt("Dimensionality of the two input matrices are not "
"consistent.");
if (mxGetClassID(prhs[0]) != mxSINGLE_CLASS
|| mxGetClassID(prhs[1]) != mxSINGLE_CLASS )
mexErrMsgTxt ("Only single precision matrices are supported.");
float * b = (float*) mxGetPr(prhs[0]); /* database vectors */
float * v = (float*) mxGetPr(prhs[1]); /* query vectors */
plhs[0] = mxCreateNumericMatrix(nq, 1, mxINT32_CLASS, mxREAL);
int * ind = (int*) mxGetPr(plhs[0]);
float * dis = NULL;
if (nlhs >= 1) {
plhs[1] = mxCreateNumericMatrix(nq, 1, mxSINGLE_CLASS, mxREAL);
dis = (float*) mxGetPr(plhs[1]);
}
int j = 0;
#pragma omp parallel shared(j)
{
#pragma omp for
for (j = 0; j < nq; j++) {
float * vj = v + j * p; // vj points to the j-th query point.
float min_dis = 1e10;
int best_ind = -1;
float * bi = b; // bi points to the i-th data point.
// The pointer changes with the for variable i.
for (int i = 0; i < n; i++, bi += p) {
float disi = 0;
for (int k = 0; k < p; k++) {
disi += (bi[k] - vj[k]) * (bi[k] - vj[k]);
}
if (disi < min_dis) {
min_dis = disi;
best_ind = i;
}
}
if (nlhs >= 1)
dis[j] = min_dis;
ind[j] = best_ind + 1; // one-based
if (best_ind == -1)
mexErrMsgTxt ("Something is wrong, ind is still -1.");
}
}
}