Почему этот код (с OpenMP в MEX-файле Matlab) дает разные результаты? - PullRequest
1 голос
/ 11 октября 2019

Я использую OpenMP для сборки MEX-файла для Matlab. Я обнаружил, что мой код дает разные результаты при использовании 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;
}

1 Ответ

1 голос
/ 11 октября 2019

Вы объявили int i,ii; перед разделом parallel. Это приводит к совместному использованию этих переменных.

Вы используете 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.

...