我想與openMP並行使用一個函數,它對一個方塊進行採樣(在一個方框中隨機選擇點,並在這些點上評估給定的函數)。我寫了下面的代碼。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原子具有不正確形式)althought我可以找到OpenMP的規格是examlpe,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);
}
}
和原子更新也是在這裏通過跟隨對數組的一種情感。
感謝和問候。
編輯--------
我同意鐸的回答。然而,似乎這個例子在這裏,在另一併行的代碼確實需要原子:行和_ + = ...,出現錯誤(併發訪問)
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_;
}
爲什麼然後在需要的?或者是否有其他錯誤?
我同意!然而,現在我並沒有理解爲什麼代碼的其他部分(我用上面的示例編輯了我的帖子)崩潰了,告訴我在'sum _ + = set_ [j] [i]'行中存在併發訪問。謝謝 ! – octoback 2012-04-16 10:55:40
@dlib:是不是應該是'#pragma omp並行減少...'?你似乎錯過了'for',這爲計算提供了完全不同的語義。 – Tudor 2012-04-16 11:38:00