我正在学习openmp
以在MATLAB mex
文件中使用。但是,我没有看到结果有任何改善。我故意在这个例子中使用三个嵌套的for循环,因为当我学习如何有效地使用openmp
时,我需要在我的实际程序中进行类似的处理。我的目标是有一个并行函数,它将double
类型的指针指向由mxMalloc
创建的数组。此函数将相应地处理这些数组。
#include <matrix.h>
#include <mex.h>
#include <omp.h>
#include <string.h>
void parallel( double *Ain, int nx, int ny, int nz, double *Aout);
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *in= mxGetPr( prhs[0] );
mwSize ndim = mxGetNumberOfDimensions( prhs[0] );
const mwSize *dims = mxGetDimensions( prhs[0] );
int nx, ny, nz, nt;
ny = dims[0];
nx = dims[1];
nz = dims[2];
double *A = (double*) mxMalloc( ny*nx*nz*sizeof(double) );
memcpy(A, in, ny*nx*nz*sizeof(double));
const mwSize d[3] = {ny, nx, nz};
plhs[0] = mxCreateNumericArray(3, d, mxDOUBLE_CLASS, mxREAL );
double *out = mxGetPr( plhs[0] );
parallel(A, nx, ny, nz, out);
}
void parallel( double *Ain, int nx, int ny, int nz, double *Aout)
{
int i, j, k;
long long ijk;
#pragma omp parallel for shared(Ain, nx, ny, nz, Aout) private(i, j, k, ijk) num_threads(8)
for( k = 0; k < nz; k++ )
for( j = 0; j < nx; j++ )
for( i = 0; i < ny; i++ )
{
ijk = i + j*ny + k*nx*ny;
Aout[ijk] = 2*Ain[ijk];
}
}
以下是Windows 64位中的编译命令以及示例:
>> mex test_openmp.cpp COMPFLAGS="/openmp $COMPFLAGS"
>> tic,A = test_openmp(ones(500,500,500));toc
时间的结果如下(左边是线程数,右边列是经过的时间):
#threads Time elapsed
_______________________
1 1.287728
2 1.213839
3 1.238359
4 1.257316
5 1.252074
6 1.268389
7 1.265825
8 1.278521
有人可以告诉我,我错过了什么导致如此可怕的表现?增加线程数不会减少所用的时间。这是否意味着函数parallel
不是计算的瓶颈?
当我尝试以下MATLAB命令时,我获得了非常快的性能。虽然我同意我的代码中还有其他东西与以下简单的MATLAB命令不同, 我希望通过增加线程数 来看到性能的巨大变化。
>> tic;A = 2*ones(500,500,500);toc;
Elapsed time is 0.380671 seconds.
>> A = ones(500,500,500); isa(A, 'double')
ans =
1
我还在ones(1000,1000,1000)
中尝试了test_openmp
,在8个线程上花了13.6
秒,而在我的机器上使用2*ones(1000,1000,1000)
只需2.8
秒。