C++ openmp并行循环的双精度化简*

C++ openmp并行循环的双精度化简*,c++,openmp,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

我在使用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 ;
}
#包括
#包括
#包括
使用名称空间std;
double my_函数(const double*x){return 1;}
int main()
{
const int nb_mom_x=5;
const int nb_mom_y=5;
常数int mesh_nb_pts_x=1000;
网格常数=1000;
双PDF_时刻[nb_mom_x][nb_mom_y];
双tmp_坐标[2];
//初始化:
对于(int k_ordre_mom_x=0;k_ordre_mom_x
问题在于,当我在mac上用
g++-7-fopenmp main.cpp-O0-o out.exe
编译这段代码时,结果是错误的。但是,如果我对以下行进行注释:
#pragma omp parallel for reduce(+:PDF_矩)
编译完这段代码后,结果是正确的


所以我猜命令的选项:
#pragma omp parallel for reduction(+:PDF_矩)
必须纠正,但我不知道如何纠正。

您在
tmp_坐标上有一个竞态条件。向量在默认情况下是共享的,因为它在循环之外声明,即使它对于每个循环迭代都是独立的。而是在循环中声明它:

#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] ;
#pragma omp并行简化(+:PDF#u)
对于(int k_mesh_x=0;k_mesh_x

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

虽然这是一个不错的问题,但请通过确保格式一致和翻译所有非英语工件来展示您的努力。感谢您的编辑和格式。您有顺序依赖关系,例如tmp_pow_x[k_ordre_mom_x]=tmp_pow_x[k_ordre_mom_x-1]……,为了并行化,需要解决的问题。@ TIM18,这正好在每个并行迭代中。我看到顺序依赖是线程局部的,所以应该是OK。我也会关注使用VLA类语法(C99特性)和C++特性。