C OpenMP并行处理两种方法的差异

C OpenMP并行处理两种方法的差异,c,multithreading,parallel-processing,openmp,race-condition,C,Multithreading,Parallel Processing,Openmp,Race Condition,我只想通过OpenMP总结评估函数的集成,使用数组保存每个步骤中计算的每个值>获取所有值的总和;取不带数组的和 代码是: double f(double x) { return sin(x)*sin(x)/(x*x+1); } 方法1 long i = 0; const long NUM_STEP = 100000; double sum[NUM_STEP]; double from = 0.0, to = 1.0; double step =

我只想通过OpenMP总结评估函数的集成,使用数组保存每个步骤中计算的每个值>获取所有值的总和;取不带数组的和

代码是:

double f(double x)
{
    return sin(x)*sin(x)/(x*x+1);
}
方法1

    long i = 0;
    const long NUM_STEP = 100000;
    double sum[NUM_STEP];
    double from = 0.0, to = 1.0;
    double step = (to - from)/NUM_STEP;
    double result = 0;

    #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];
    printf("%lf", result);
长i=0;
const long NUM_STEP=100000;
双和[NUM_步];
双精度自=0.0,至=1.0;
双步=(到-从)/NUM_步;
双结果=0;
#用于共享(总和)num_线程的pragma omp并行(4)

对于(i=0;iTL;DR,第一种方法没有竞争条件,而第二种方法有竞争条件

第一种方法没有竞争条件,而第二种方法有竞争条件。即,在第一种方法中:

#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];
实际上,您可以在此版本上做一点小小的改进;您可以不使用与
NUM_STEP
数量相同的大小来分配数组
sum
,而只使用与线程数量相同的大小来分配它,并且每个线程将保存在与其
ID
相同的位置,即:

for(i=0; i<NUM_STEP; i++)
    result += sum[i];
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用于减少(+:result)num_线程(4)

对于(i=0;iTL;DR,第一种方法没有竞争条件,而第二种方法有竞争条件

第一种方法没有竞争条件,而第二种方法有竞争条件。即,在第一种方法中:

#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];
实际上,您可以在此版本上做一点小小的改进;您可以不使用与
NUM_STEP
数量相同的大小来分配数组
sum
,而只使用与线程数量相同的大小来分配它,并且每个线程将保存在与其
ID
相同的位置,即:

for(i=0; i<NUM_STEP; i++)
    result += sum[i];
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用于减少(+:result)num_线程(4)
对于(i=0;i