为啥这段代码(在 Matlab 的 MEX 文件中使用 OpenMP)给出不同的结果?

Posted

技术标签:

【中文标题】为啥这段代码(在 Matlab 的 MEX 文件中使用 OpenMP)给出不同的结果?【英文标题】:Why this code (with OpenMP in MEX-file of Matlab) give different results?为什么这段代码(在 Matlab 的 MEX 文件中使用 OpenMP)给出不同的结果? 【发布时间】:2019-10-11 08:55:04 【问题描述】:

我正在使用 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;

【问题讨论】:

尝试将 private(ii) 添加到您的 openmp 编译指示 @Gilles 如果在ii 循环中,有很多变量。我如何将它们全部私有化?我不知道将两个或多个变量设为私有。 【参考方案1】:

您已在 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来编写。

【讨论】:

以上是关于为啥这段代码(在 Matlab 的 MEX 文件中使用 OpenMP)给出不同的结果?的主要内容,如果未能解决你的问题,请参考以下文章

如何诊断为啥在 MATLAB 中执行 .mex 文件时无法加载 .so 文件?

为啥到达 MEX 文件的最后一行后返回 Matlab 需要这么长时间?

为啥 MEX 代码比 matlab 代码慢得多?

如何在 MATLAB MEX 文件中使用 FFTW lib 文件?

Mex 文件执行中的错误,Matlab 窗口

如何找到 Matlab mex 文件的代码?