TL;博士
第一种方法没有
比赛条件
而第二种方法具有。
第一种方法没有竞争条件,而第二种方法有。即,在第一种方法中:
#pragma omp parallel for shared(sum) num_threads(4)
for(i=0; i<NUM_STEP; i++)
sum[i] = step*f(from+i*step);
for(i=0; i<NUM_STEP; i++)
result += sum[i];
每个线程都保存操作的结果
step*f(from+i*step);
在阵列的不同位置
sum[i]
在那之后
主人
线程,按顺序减少数组上保存的值
sum
即:
for(i=0; i<NUM_STEP; i++)
result += sum[i];
实际上,您可以在这个版本上做一些改进;而不是分配数组
总和
大小与数量相同
NUM_STEP
,您可以将其分配为与线程数相同的大小,每个线程将保存在与其线程数相等的位置
ID
即:
int total_threads = 4;
double sum[total_threads];
#pragma omp parallel num_threads(total_threads)
{
int thread_id = omp_get_thread_num();
for(i=0; i<NUM_STEP; i++)
sum[thread_id] += step*f(from+i*step);
for(i=0; i< total_threads; i++)
result += sum[i];
}
尽管如此,最好的方法将是实际修复第二种方法。
第二种方法是
比赛条件
关于变量的更新
result
:
#pragma omp parallel for shared(result) num_threads(4)
for(i=0; i<NUM_STEP; i++)
result += step*f(from+i*step);
因为
结果
变量由多个线程以非线程安全的方式并发更新。
为了解决这个问题
比赛条件
你需要使用
reduction
条款:
#pragma omp parallel for reduction(+:result) num_threads(4)
for(i=0; i<NUM_STEP; i++)
result += step*f(from+i*step);