为什么此代码(在 Matlab 的 MEX 文件中使用 OpenMP)给出不同的结果?

Why this code (with OpenMP in MEX-file of Matlab) give different results?

我正在使用 OpenMP 为 Matlab 构建 MEX 文件。我发现我的代码在使用 OpenMP 进行加速时给出了不同的结果。我做了一个简单的例子如下。它假设计算每个向量的平均值。每个向量中的每个元素都是1。所以结果应该是一个1的数组。但结果有时会有其他数字,比如0.333、0.666或0。我认为这一定与OpenMP for循环有关。但我想不通。任何建议或想法将不胜感激。

#include "mex.h"
#include <vector>
#include <iostream>
#include <algorithm>
#include <numeric>
#include <omp.h>
using namespace std;

void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
    int xx=8;
    int yy[]={2,3,4,5,6,7,8,9};
    vector<vector<double>> data(xx);
    vector<double>mean0(xx);
    int i,ii;
#pragma omp parallel 
{ 
 #pragma omp for
    for (i = 0; i < xx; i++) {
        data[i].resize(yy[i]);
        for (ii = 0; ii < yy[i]; ii++) {
            data[i][ii]=1;
        }
        mean0[i] =accumulate( data[i].begin(), data[i].end(), 0.0)/data[i].size();  
    }
}

    // output
    plhs[0] = mxCreateDoubleMatrix(mean0.size(), 1, mxREAL);
    copy(mean0.begin(), mean0.end(), mxGetPr(plhs[0]));
    return;
}

您在 parallel 部分之前声明了 int i,ii;。这导致这些变量被共享。

您正在使用 C++,在您首先初始化变量的地方声明变量。在循环变量的情况下,这看起来像这样:

for (int i = 0; i < xx; i++) {
   data[i].resize(yy[i]);
   for (int ii = 0; ii < yy[i]; ii++) {
      data[i][ii]=1;
   }
   mean0[i] = ...
}

这提高了代码的可读性,也解决了您的 OpenMP 问题。


顺便说一句,上面的循环也可以通过调用 std::fill.

来编写