作为非MATLAB控,却选择MATLAB进行项目的研究,主要还是因为MATLAB使用起来实在太方便了。因此,它的缺陷也很明显,效率不高。内部定义的任何函数,如果我们使用C语言重写,效率一般都能得到一定的提升。
而对于复杂度更高的算法,则需要进一步使用并行编程的方法,比如多线程。那么,在我们使用MATLAB进行项目的主体框架设计后,如何调用使用C语言编写的代码呢?首先,C语言程序肯定需要经过编译,生成动态链接库文件。
如何编写openmp程序以及编译:
#include "mex.h"
#include <omp.h>
void paralleltest(int N)
{
omp_set_num_threads(N);
#pragma omp parallel
{
int id;
id = omp_get_thread_num();
mexPrintf( "%d" , id);
}
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int nthread;
if(nrhs == 0)
nthread = 2;
else
nthread = mxGetScalar(prhs[0]);
paralleltest(nthread);
}
如何编译呢?打开mex编译器,选择visual c++ 2010。
>>mex COMPFLAGS="$COMPFLAGS /openmp" testparallel.c
写一个生成二维随机数数组的openmp程序:
#include "mex.h"
#include <cstdlib>
#include <ctime>
#include <omp.h>
void calc(double * p, int n)
{
omp_set_num_threads(8);
int i;
#pragma omp parallel for //private(i)
for (i = 0; i <n; ++i)
{
p[i] = i;
//printf("i = %d, Thread = %d\n", i, omp_get_thread_num());
}
}
void rand(double * p, int n)
{
srand(( unsigned int )time(NULL));
omp_set_num_threads(4);
int i;
#pragma omp parallel for
for(i = 0; i < n; ++i)
{
p[i] = rand()%256;
//printf("i = %d, Thread = %d\n", i, omp_get_thread_num());
}
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxAssert(nlhs == 1 && nrhs == 1, "Error:The output/input array should be only one");
mxAssert(mxGetM(prhs[0]) == 1 && mxGetN(prhs[0]) == 2, "Error: cols and rows");
double* p_in = static_cast <double *>(mxGetData(prhs[0]));
int m = static_cast< int >(p_in[0]);
int n = static_cast< int >(p_in[1]);
plhs[0] = mxCreateDoubleMatrix(m, n, mxREAL);
double* dynamicData = static_cast <double *>(mxGetData(plhs[0]));
//calc(dynamicData, m*n);
rand(dynamicData, m*n);
//mxSetData(plhs[0], dynamicData);
}
编译生成可执行的mex文件:
>> mex COMPFLAGS="$COMPFLAGS -openmp" rand2D.cpp
生成300*300的随机数数组:
>> tic;rand2D([300, 300]);toc
Elapsed time is 0.188277 seconds.
Elapsed time is 0.188277 seconds.
使用MATLAB内部函数randint()生成随机数数组:
>> tic;randint(300, 300, [0, 256]);toc;
Elapsed time is 0.653515 seconds.
>> tic;randint(300, 300, [0, 256]);toc;
Elapsed time is 0.653515 seconds.
可以看出在设置线程数为4的情况下,与MATLAB内部函数randint()相比,openmp程序的性能为4倍。