openmp并行循环减少双*

时间:2017-07-11 08:27:22

标签: c++ openmp

我在使用OpenMP进行数组(double **)的减少(求和)时遇到问题。代码是:

#include <stdlib.h>
#include <iostream>
#include <omp.h>

using namespace std ;

double my_function(const double * x) { return 1 ; }

int main()
{
    const int nb_mom_x = 5 ;
    const int nb_mom_y = 5 ;
    const int mesh_nb_pts_x = 1000 ;
    const int mesh_nb_pts_y = 1000 ;
    double PDF_moments[nb_mom_x][nb_mom_y] ;
    double tmp_coordinates[2] ;

    // Initialisation :
    for ( int k_ordre_mom_x = 0 ; k_ordre_mom_x < nb_mom_x ; k_ordre_mom_x++ )
        for( int k_ordre_mom_y = 0 ; k_ordre_mom_y < nb_mom_y ; k_ordre_mom_y++ )
            PDF_moments[k_ordre_mom_x][k_ordre_mom_y] = 0.0 ;

    #pragma omp parallel for reduction(+:PDF_moments)
    for ( int k_mesh_x = 0 ; k_mesh_x < mesh_nb_pts_x ; k_mesh_x++ )
    {
        // Abscissa of the point in x:
        tmp_coordinates[0] = (double) k_mesh_x/mesh_nb_pts_x ;

        // Evaluation of the powers of x:
        double tmp_pow_x[nb_mom_x] ;
        tmp_pow_x[0] = 1.0 ;
        for ( int k_ordre_mom_x = 1 ; k_ordre_mom_x < nb_mom_x ; k_ordre_mom_x++ )
            tmp_pow_x[k_ordre_mom_x] = tmp_pow_x[k_ordre_mom_x-1] * tmp_coordinates[0] ;

        for ( int k_mesh_y = 0 ; k_mesh_y < mesh_nb_pts_y ; k_mesh_y++ )
        {
            // Abscissa of the point in y:
            tmp_coordinates[1] = (double) k_mesh_y/mesh_nb_pts_y ;

            // Evaluation of the powers of y:
            double tmp_pow_y[nb_mom_y] ;
            tmp_pow_y[0] = 1.0 ;
            for ( int k_ordre_mom_y = 1 ; k_ordre_mom_y < nb_mom_x ; k_ordre_mom_y++ )
                tmp_pow_y[k_ordre_mom_y] = tmp_pow_y[k_ordre_mom_y-1] * tmp_coordinates[0] ;

            // Evaluation of the function:
            double tmp_function = my_function( tmp_coordinates ) ;

            for( int k_ordre_mom_y = 0 ; k_ordre_mom_y < nb_mom_y ; k_ordre_mom_y++ )
                for ( int k_ordre_mom_x = 0 ; k_ordre_mom_x < nb_mom_x ; k_ordre_mom_x++ )
                    PDF_moments[k_ordre_mom_x][k_ordre_mom_y] += tmp_function * tmp_pow_x[k_ordre_mom_x] * tmp_pow_y[k_ordre_mom_y] ;

        }
    }

    for ( int k_ordre_mom_x = 0 ; k_ordre_mom_x < nb_mom_x ; k_ordre_mom_x++ )
        for( int k_ordre_mom_y = 0 ; k_ordre_mom_y < nb_mom_y ; k_ordre_mom_y++ )
            PDF_moments[k_ordre_mom_x][k_ordre_mom_y] *= (1.0/mesh_nb_pts_x)*(1.0/mesh_nb_pts_y) ;    


    // Display of the moments of the function:
    printf("\n+-------+") ;
    for ( int k_ordre_mom_y = 0 ; k_ordre_mom_y < nb_mom_y ; k_ordre_mom_y++ ) printf("------------+") ;
    printf("\n| Ordre |") ;
    for ( int k_ordre_mom_y = 0 ; k_ordre_mom_y < nb_mom_y ; k_ordre_mom_y++ ) printf("  % 9.1d |",k_ordre_mom_y) ;
    printf("\n+-------+") ;
    for ( int k_ordre_mom_y = 0 ; k_ordre_mom_y < nb_mom_y ; k_ordre_mom_y++ ) printf("------------+") ;
    for ( int k_ordre_mom_x = 0 ; k_ordre_mom_x < nb_mom_x ; k_ordre_mom_x++ )
    {
        printf("\n| % 5.1d |",k_ordre_mom_x ) ;
        for( int k_ordre_mom_y = 0 ; k_ordre_mom_y < nb_mom_y ; k_ordre_mom_y++ )
        {
            printf(" % 1.3e |" ,PDF_moments[k_ordre_mom_x][k_ordre_mom_y] ) ;
        }
    }
    printf("\n+-------+") ;
    for ( int k_ordre_mom_y = 0 ; k_ordre_mom_y < nb_mom_y ; k_ordre_mom_y++ ) printf("------------+") ;

    printf("\n");
    return 0 ;
}

当我在mac上使用g++-7 -fopenmp main.cpp -O0 -o out.exe编译此代码时结果是错误的,问题如下。但是,如果我在编译此代码后对该行进行评论:#pragma omp parallel for reduction(+:PDF_moments),结果是正确的。

所以我的猜测是命令的选项:#pragma omp parallel for reduction(+:PDF_moments)必须得到纠正,但我不知道该怎么做。

1 个答案:

答案 0 :(得分:0)

tmp_coordinates上有竞争条件。默认情况下,向量是共享的,因为它是在循环之外声明的,即使它对每个循环迭代都是独立的。相反,在循环中声明它:

#pragma omp parallel for reduction(+:PDF_moments)
for ( int k_mesh_x = 0 ; k_mesh_x < mesh_nb_pts_x ; k_mesh_x++ )
{
    double tmp_coordinates[2] ;

然后它对每个线程都是私有的。

相关问题