首页 > 解决方案 > 使用 OpenMP 缩减时的精度损失

问题描述

我在 Fortran 中编写了一个简单的子例程,用于使用 OpenMP 缩减并行化进行向量的点积。然而,它的结果dot_product与非openMP做循环求和有很大不同。请看下面的代码:

program main
  use iso_fortran_env
  implicit none
  real(real64), allocatable  :: x(:)
  real(real64)               :: x_dot
  integer(int32)             :: i, n
  n = 1000000
  allocate(x(n))
  x = 0.3_real64
  print *, "sum:     ", dot_product(x,x)
  x_dot = 0.0_real64
  do i = 1, n
    x_dot = x_dot + x(i)*x(i)
  enddo
  print *, "loop:    ", x_dot
  x_dot= 0.0_real64
  !$omp parallel do private(i) reduction(+:x_dot)
  do i = 1, n
    x_dot = x_dot + x(i)*x(i)
  enddo
  !$omp end parallel do
  print *,"omp red: ", x_dot
end program main

生成的输出:

sum:        89999.999997827967
loop:       89999.999997827967
omp red:    90000.000000129017

正如您所看到的 omp reduction,我们在单精度级别上有所不同。我在某处得到一些比赛条件吗?

gfortran 7.5

编译标志:-O3 -fopenmp

OMP_NUM_THREADS=4

标签: parallel-processingfortranopenmphpc

解决方案


推荐阅读