OpenMP:并行化(近似)代码使其不仅更快,而且更准确。为什么呢?

时间:2017-05-19 10:57:03

标签: c algorithm parallel-processing openmp

我已经并行化了一个简单的代码,用于在数值上计算函数的积分。我使用函数y=2*sqrt(1-x^2)从-1到1.这个积分等于Pi。

算法是计算积分的最简单方法,我猜大家都是在学校里学到的。我"画"功能下的小尺寸矩形并计算它们的面积。

顺序算法是:

double calc_integral_seq(int left_bound, int right_bound){
  int i;
  double x, sum=0.0;
  double step = 1.0/ (double) STEPS;

  for(i=left_bound*STEPS; i<right_bound*STEPS; i++){
        x = (i+0.5)*step;
        sum += f(x);
  }
return sum*step;
}

现在,当我并行化此代码时(例如,仅使用for-loop构造#pragma omp parallel for private(x) reduction(+:sum)),对于大量STEPS,算法会更快。

但它也更准确!怎么可能?这是一个确定性的算法,它应该计算完全相同的值或者我错了吗?怎么解释这个?

1 个答案:

答案 0 :(得分:2)

这是一个四舍五入的问题。每当您将非常小的数字添加到非常大的数字时,就会出现舍入误差,因为具有大指数的浮点数无法准确描述小的变化。每次添加的舍入误差随着sum值的增加而增加。

通过并行计算,本地sum不会像串行循环一样大。因此在本地,舍入误差较小。对于全局sum的总和,本地结果更加接近,因此舍入较少。

避免浮点舍入错误的常规算法是Kahan summationpairwise summation