0

これは、ニューラル ネットワークの逆伝播アルゴリズム コードの一部です。

この場合、for( pt=0; pt< N_PT_pair; pt++) ループを並列化したいのですが、 for(epoch=0; epoch< MaxEpoch; epoch++) は並列化できません。

initialize W1[ ] [ ] and W2[ ][ ] with random values
for(epoch=0; epoch<MaxEpoch; epoch++)
     dW1[ ][ ]=0.0; dW2[ ][ ]=0.0; //sum of weight corrections
     sse = 0; // Sum of square of errors
     for( pt=0; pt<N_PT_pair; pt++)
          input = pattern[pt];
          compute output  // procedure as above
          compare target[pt] and output and
          compute dW2[ ][ ] += ... // procedure to be described
          compute dW1[ ][ ] += ... // procedure to be described
          for(k=1; k<=Noutput; k++) 
              sse+=pow((target[pt][k]-output[k]),2);
     end pt for loop   
     cout << "mean square error" << sse/N_PT_pair;
     W1[ ][ ] += rate*dW1[ ][ ]
     W2[ ][ ] += rate*dW2[ ][ ]
end epoch for loop

これらは、配列の割り当てと割り当て解除のためのコードです

double** allocate_matrix(int rows,int cols) 
{    
    double **a;

    a = new double*[rows];    
    if(a==NULL){cout<<"matrix allocation failed"<<endl;exit(-1);}

    for (int j=0;j<rows;j++){   
       a[j] =  new double[cols];
       if(a[j]==NULL) {cout<<"matrix allocation failed"<<endl;exit(-1);}    
    }

    return a;
}

int deallocate_matrix(double**a,int rows)    
{
    for(int i=0;i<rows;i++)
       delete [] a[i];
    delete [ ] a;    
    return 0;
}

コードの並列化を手伝ってもらえますか?

4

1 に答える 1

1

内部ループの反復が互いに独立している場合は、単純に 1 つの OpenMP コンストラクトから開始できます。

#pragma omp parallel for private(input,k) reduction(+:sse)
for( pt=0; pt<N_PT_pair; pt++)
     input = pattern[pt];
     compute output  // procedure as above
     compare target[pt] and output and
     compute dW2[ ][ ] += ... // procedure to be described
     compute dW1[ ][ ] += ... // procedure to be described
     for(k=1; k<=Noutput; k++) 
         sse+=pow((target[pt][k]-output[k]),2);
end pt for loop

dW1orの要素がdW2複数回の繰り返しで更新されない場合、これはうまく機能します。そうしないと、アトミック アクセスが必要になり、パフォーマンスが低下します (OpenMP は、C/C++ の配列の削減をまだサポートしていません)。

ネットワークの重みが多数ある場合は、同じ方法で乗算を並列化することもできます。

OpenMP のオーバーヘッドを削減するために、並列領域を外側のループの外にさらに移動することができます。またsinglemasterOpenMP ディレクティブを使用して、単一のスレッドでのみ実行する必要があるコードを分離することもできます。

#pragma ompコンパイラがディレクティブを理解するには、OpenMP サポートを有効にする必要があります。これがどのように正確に行われるかは、コンパイラ固有です。

  • -fopenmpGCC 用
  • -openmpインテル C/C++ コンパイラー用
  • -xopenmpOracle Solaris Studio の場合
  • プロジェクトのプロパティ -> MS Visual Studio の場合はその他
于 2012-05-29T12:28:31.557 に答える