C++ OpenMP reduction子句与嵌套循环的使用

C++ OpenMP reduction子句与嵌套循环的使用,c++,performance,openmp,C++,Performance,Openmp,我有一个函数的当前版本: void* function(const Input_st *Data, Output_st *Image) { int i,j,r,Offset; omp_set_num_threads(24); #pragma omp parallel for schedule(static) shared(Data,Image),\ private(i,j,r,Offset)

我有一个函数的当前版本:

    void*
    function(const Input_st *Data, Output_st *Image)
    {
        int i,j,r,Offset;
        omp_set_num_threads(24);
        #pragma omp parallel for schedule(static) shared(Data,Image),\ 
        private(i,j,r,Offset)
        for (i = 0; i < Data->NX; i++)
        {
            for (j = 0; j < (Data->NZ); j++)
            {
                for (r = 0; r < Data->NR; r++)
                {
                    Offset                = i*Data->NR*Data->NZ + j*Data->NR + r;
                    Image->pTime[Offset] = function2()
                }
            }
        }
        return NULL;
    }
我有Seg故障。我假设我需要使用
reduce
子句,比如
reduce(+:pTime)

  • 首先,这里的目的是加快功能,我想知道这样的更改是否会显著加快?(比如使用的缓存更少?)
  • 第二,我尝试对其进行基准测试,但失败了!我认为这里的问题可以通过使用reduce子句来解决,但是由于循环是嵌套的,所以这个问题对我来说并不那么简单

  • 这里不需要任何类型的
    缩减
    子句。但是,目前,所有线程都使用相同的指针并更新相同的内存位置(在分配给
    pTime
    的值中有竞争条件,因此我怀疑会发生崩溃)

    因此,您需要以私有方式定义指针(通常是在
    并行
    区域内声明指针,并将每个线程单独设置为一个有意义的值。然后可以按您想要的方式递增指针

    下面是代码修复后的样子(显然未测试):

    void*函数(常量输入*数据,输出*图像){
    #计划(静态)num_线程的pragma omp并行(24)
    对于(int i=0;iNX;i++){
    双*pTime=图像->pTime+i*数据->NR*数据->新西兰;
    对于(int j=0;jNZ;j++){
    对于(int r=0;rNR;r++){
    *pTime=function2();
    pTime++;
    }
    }
    }
    返回NULL;
    }
    
    我通过替换j循环中的*pTime声明(而不是I,因为偏移量取决于j)尝试了它,它成功了!但是我没有看到性能方面的显著改进!谢谢!!
        void*
        function(const Input_st *Data, Output_st *Image)
        {
            int i, j, r;
            double *pTime = Image->pTime;
            omp_set_num_threads(24);
            #pragma omp parallel for schedule(static) shared(Data,Image),\ 
            private(i,j,r)
            for (i = 0; i < Data->NX; i++)
            {
                for (j = 0; j < (Data->NZ); j++)
                {
                    for (r = 0; r < Data->NR; r++)
                    {
                        *pTime = function2()
                        pTime++;
                    }
                }
            }
            return NULL;
        }
    
    void* function( const Input_st *Data, Output_st *Image ) {
        #pragma omp parallel for schedule( static ) num_threads( 24 )
        for ( int i = 0; i < Data->NX; i++ ) {
            double *pTime = Image->pTime + i * Data->NR * Data->NZ;
            for ( int j = 0; j < Data->NZ; j++ ) {
                for ( int r = 0; r < Data->NR; r++ ) {
                    *pTime = function2();
                    pTime++;
                }
            }
        }
        return NULL;
    }