4

我想并行化这个函数,但我是 open mp 的新手,如果有人能帮助我,我将不胜感激:

void my_function(float** A,int nbNeurons,int nbOutput, float* p, float* amp){
   float t=0;
   for(int r=0;r<nbNeurons;r++){
      t+=p[r];
   }

   for(int i=0;i<nbOutput;i++){
      float coef=0;
      for(int r=0;r<nbNeurons;r++){
       coef+=p[r]*A[r][i];
      }
   amp[i]=coef/t;
   }
}

由于双循环,我不知道如何正确并行化它,目前,我只想做一个: #pragma omp parallel for reduction(+:t)

但我认为这不是通过 openMp 加快计算速度的最佳方式。

预先感谢,

4

1 回答 1

8

首先:我们需要了解上下文。您的分析器告诉您在哪里花费的时间最多?

通常,粗粒度并行化效果最好,正如@Alex 所说:并行化外部 for 循环。

void my_function(float** A,int nbNeurons,int nbOutput, float* p, float* amp)
{
    float t=0;
    for(int r=0;r<nbNeurons;r++)
        t+=p[r];

#pragma parallel omp for 
    for(int i=0;i<nbOutput;i++){
        float coef=0;
        for(int r=0;r<nbNeurons;r++){
            coef+=p[r]*A[r][i];
        }
        amp[i]=coef/t;
    }
}

根据实际体积,在后台计算 t 并将除法移出并行循环可能会很有趣:

void my_function(float** A,int nbNeurons,int nbOutput, float* p, float* amp)
{
    float t=0;
#pragma omp parallel shared(amp)
    {
#pragma omp single nowait // only a single thread executes this
        {
            for(int r=0;r<nbNeurons;r++)
                t+=p[r];
        }

#pragma omp for 
        for(int i=0;i<nbOutput;i++){
            float coef=0;
            for(int r=0;r<nbNeurons;r++){
                coef+=p[r]*A[r][i];
            }
            amp[i]=coef;
        }

#pragma omp barrier
#pragma omp master // only a single thread executes this
        {
            for(int i=0; i<nbOutput; i++){
                amp[i] /= t;
            }
        }
    }
}

注意未经测试的代码。OMP 有时具有棘手的语义,所以我可能错过了那里的“共享”声明。不过,分析器不会很快通知您。

于 2012-08-27T14:50:53.930 回答