まず第一に、私たちは文脈を知る必要があります。あなたのプロファイラーは、最も多くの時間が費やされていることをどこに伝えますか?
一般に、@ 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にはトリッキーなセマンティクスがあることがあるため、そこで「共有」宣言を見逃した可能性があります。ただし、プロファイラーがすぐに通知しないものはありません。