【问题标题】:OpenMP: parallelizing (Approximation) Code makes it not only faster, but more accurate. Why?OpenMP:并行化(近似)代码不仅更快,而且更准确。为什么?
【发布时间】:2017-05-19 10:57:03
【问题描述】:

我已经并行化了一个简单的代码,用于计算函数的数值积分。我将它与从 -1 到 1 的函数 y=2*sqrt(1-x^2) 一起使用。这个积分等于 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 循环构造 #pragma omp parallel for private(x) reduction(+:sum)),对于大尺寸 STEPS,算法要快得多。

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

【问题讨论】:

  • 这是一种确定性算法 在实践中,最好将依赖于浮点运算的并行算法视为仅近似确定性,因为它们通常会放弃对顺序的控制运算,并且我们都知道 f-p 算术不是正确关联的。正如祖兰的回答所解释的那样。

标签: c algorithm parallel-processing openmp


【解决方案1】:

这是一个四舍五入的问题。每当你把一个非常小的数字加到一个非常大的数字上时,都会出现舍入误差,因为这个微小的变化并不能用大指数的浮点数来准确描述。每次相加的舍入误差随着sum 值的增加而增加。

通过并行计算,本地sum 不会像串行循环那样增长。所以在本地,舍入误差较小。也是对全局sum的求和,局部结果更接近,因此舍入较少。

避免浮点舍入错误的一般算法是Kahan summationpairwise summation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    • 2018-01-01
    • 1970-01-01
    相关资源
    最近更新 更多