ボックスをサンプリングしている関数をopenMPと並列化したいと思います(ボックス内のポイントをランダムに選択し、これらのポイントで特定の関数を評価します)。次のコードを書きました。
//storing points
double** points_ = new double*[N-m];
for(int i=0;i<N-m;i++)
{
points_[i]=new double[ndim];
}
double* evals_ = new double[N-m];
#pragma omp parallel for
for(int i=0;i<N-m;i++)
{
double* pt_ = randomPoint(lower,upper);
for(int k=0;k<ndim;k++)
{
points_[i][k]=pt_[k];
}
evals_[i]=evalFunc(pt_);
delete pt_;
}
ただし、私はこのコードに自信がありません。evals_とpoints_はeauchスレッドで更新されます。そこにいくつかのアトミックステートメントを追加することを考えています。
#pragma omp parallel for
for(int i=0;i<N-m;i++)
{
double* pt_ = randomPoint(m_lower,m_upper);
for(int k=0;k<m_ndim;k++)
{
#pragma omp atomic update
points_[i][k]=pt_[k];
}
#pragma omp atomic update
evals_[i]=evalFunc(pt_);
delete pt_;
}
しかし、これは非常に非効率的であると私は恐れています。より正確に書くためのアドバイスはありますか?そして...これはコンパイルされていません...(エラー:#pragma ompアトミックに続く式は不適切な形式です)ただし、openMP仕様、A22でその例を見つけることができます
void atomic_example(float *x, float *y, int *index, int n)
{
int i;
#pragma omp parallel for shared(x, y, index, n)
for (i=0; i<n; i++) {
#pragma omp atomic update
x[index[i]] += work1(i);
y[i] += work2(i);
}
}
また、アトミック更新の後には、アレイへの影響もあります。
ありがとう、よろしく。
編集 - - - -
私はチューダーの答えに同意します。ただし、この例では、別の並列化されたコードでアトミックが必要なようです。行sum _ + = ...で、エラーが発生します(同時アクセス)
for(i=0;i<m_ndim;i++)
{
double sum_=0;
#pragma omp parallel reduction(+:sum_)
for(j=0;j<m_npts;j++)
{
sum_ += set_[j][i];
}
Sum_[i] = sum_;
}
なぜそれが必要なのですか?それとも他に何かが間違っていますか?