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 に答える