如何并行处理以下for循环

时间:2019-06-24 15:05:07

标签: c openmp

我正在尝试整合曲线功能,并将串行代码转换为并行程序,我使用的是openMP。

我已经使用openMP parallel for并行化了for循环,并获得了较少的程序时间,但是问题是结果不是预期的,线程中有些东西弄乱了,我想知道如何并行化N个线程的for循环。

#include <stdio.h>
#include <omp.h>
#include <math.h>

double f(double x){
  return sin(x)+0.5*x;
}


int main(){
  int n=134217728,i;
  double a=0,b=9,h,x,sum=0,integral;

  double start = omp_get_wtime();
  h=fabs(b-a)/n;

  omp_set_dynamic(0);
  omp_set_num_threads(64);
  #pragma omp parallel for reduction (+:sum) shared(x)
  for(i=1;i<n;i++){
    x=a+i*h;
    sum=sum+f(x);
  }

  integral=(h/2)*(f(a)+f(b)+2*sum);
  double end = omp_get_wtime();
  double time = end - start;
  printf("Execution time: %2.3f seconds\n",time);
  printf("\nThe integral is: %lf\n",integral);
}

预期输出为22.161130,但是每次运行程序时,输出都会变化。

1 个答案:

答案 0 :(得分:-2)

您尝试并行化的循环在每次迭代中都会修改相同的变量xsum,这对并行化非常麻烦。

您可以重写代码以使并行化的路径更加显而易见:

#include <stdio.h>
#include <omp.h>
#include <math.h>

double f(double x) {
    return sin(x) + 0.5 * x;
}

int main() {
    int n = 1 << 27, i, j;
    double a = 0, b = 9, h, x, sum, integral;
    double sums[64] = { 0 };

    double start = omp_get_wtime();
    h = fabs(b - a) / n;

    omp_set_dynamic(0);
    omp_set_num_threads(64);
    #pragma omp parallel for

    for (j = 0; j < 64; j++) {
        for (i = 0; i < n; i += 64) {
            sums[j] += f(a + i * h + j * h);
        }
    }
    sum = 0;
    for (j = 0; j < 64; j++) {
        sum += sums[i];
    }

    integral = (h / 2) * (f(a) + f(b) + 2 * sum);
    double end = omp_get_wtime();
    double time = end - start;
    printf("Execution time: %2.3f seconds\n", time);
    printf("\nThe integral is: %lf\n", integral);
    return 0;
}