在MATLAB / MEX中使用openmp没有任何改进

时间:2014-12-24 03:02:58

标签: c matlab openmp mex

我正在学习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秒。

0 个答案:

没有答案