OpenMP减少子句与嵌套循环的用法

时间:2018-11-15 11:09:46

标签: 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)
        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;
    }

它工作得很好,但是我想删除变量Offset的计算,并使用指向成员Image->pTimeR的指针,然后递增,如下所示:

    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;
    }

我遇到段故障。我假设我需要使用reduction之类的reduction(+:pTime)子句。

  1. 首先,这里的目的是加快功能,我想知道这样的改变是否会大大加快速度? (要使用更少的缓存吗?)
  2. 第二,好吧,我尝试对其进行基准测试,但未能成功!我认为这里的问题可以通过使用reduce子句解决,但是由于循环是嵌套的,因此问题对我而言并不是那么简单。

1 个答案:

答案 0 :(得分:1)

这里不需要任何reduction子句。但是,此刻,所有线程都使用相同的指针并更新相同的内存位置(竞争条件分配给pTime的值中,因此我怀疑是崩溃了。)

因此,您需要以私有方式定义指针(通常是通过在parallel区域内声明指针),然后将每个线程的指针分别设置为有意义的值,然后可以按照需要的方式对其进行递增。

这里是一旦固定(未经明显测试)的代码:

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;
}