我有这段并行化的代码。
int i,n; double area,pi,x;
area=0.0;
#pragma omp parallel for private(x) reduction (+:area)
for(i=0; i<n; i++){
x= (i+0.5)/n;
area+= 4.0/(1.0+x*x);
}
pi = area/n;
据说减少将消除如果我们不使用减少可能发生的竞争条件。我仍然想知道我们是否需要为区域添加lastprivate,因为它在并行循环之外使用并且在它之外是不可见的。还有减少还包括这个吗?
答案 0 :(得分:0)
Reducing负责为每个线程制作area
的私有副本。一旦平行区域结束区域在一个原子操作中减少。换句话说,公开的area
是每个线程的所有私有area
的聚合。
thread 1 - private area = compute(x)
thread 2 - private area = compute(y)
thread 3 - private area = compute(z)
reduction step - public area = area<thread1> + area<thread2> + area<thread3> ...
答案 1 :(得分:0)
您不需要lastprivate。为了帮助您了解缩减的执行方式,我认为了解如何使用atomic
完成此操作非常有用。以下代码
float sum = 0.0f;
pragma omp parallel for reduction (+:sum)
for(int i=0; i<N; i++) {
sum += //
}
相当于
float sum = 0.0f;
#pragma omp parallel
{
float sum_private = 0.0f;
#pragma omp for nowait
for(int i=0; i<N; i++) {
sum_private += //
}
#pragma omp atomic
sum += sum_private;
}
虽然这个替代方案有更多代码,但显示如何使用更复杂的运算符会很有帮助。起诉reduction
时的一个限制是atomic
仅支持一些基本操作符。如果您想使用更复杂的运算符(例如SSE / AVX添加),那么您可以将atomic
替换为critical
reduction with OpenMP with SSE/AVX