我试图在Fortran 90中使用OpenMP来将do循环与函数调用并行化。首先列出的代码运行正常。接下来列出的代码没有。我收到了分段错误。
第一个程序:$ gfortran -O3 -o output -fopenmp OMP10.f90
program OMP10
!$ use omp_lib
IMPLICIT NONE
integer, parameter :: n = 100000
integer :: i
real(kind = 8) :: sum,h,x(0:n),f(0:n),ZBQLU01
!$ call OMP_set_num_threads(4)
h = 2.d0/dble(n)
!$OMP PARALLEL DO PRIVATE(i)
do i = 0,n
x(i) = -1.d0+dble(i)*h
f(i) = 2.d0*x(i)
end do
!$OMP END PARALLEL DO
sum = 0.d0
!$OMP PARALLEL DO PRIVATE(i) REDUCTION(+:SUM)
do i = 0,n-1
sum = sum + h*f(i)
end do
!$OMP END PARALLEL DO
write(*,*) "The integral is ", sum
end program OMP10
第二个计划:$ gfortran -O3 -o output -fopenmp randgen.f OMP10.f90
program OMP10
!$ use omp_lib
IMPLICIT NONE
integer, parameter :: n = 100000
integer :: i
real(kind = 8) :: sum,h,x(0:n),f(0:n),ZBQLU01
!$ call OMP_set_num_threads(4)
h = 2.d0/dble(n)
!$OMP PARALLEL DO PRIVATE(i)
do i = 0,n
x(i) = ZBQLU01(0.d0)
end do
!$OMP END PARALLEL DO
sum = 0.d0
!$OMP PARALLEL DO PRIVATE(i) REDUCTION(+:SUM)
do i = 0,n-1
sum = sum + h*f(i)
end do
!$OMP END PARALLEL DO
write(*,*) "The integral is ", sum
end program OMP10
在上面的命令中,randgen.f
是一个包含函数ZBQLU01
的库。
答案 0 :(得分:0)
您不能只从并行区域调用任何函数。该函数必须是线程安全的。请参阅What is meant by "thread-safe" code?和https://en.wikipedia.org/wiki/Thread_safety。
您的功能与线程安全完全相反,这对于随机数生成器来说非常典型。只需注意源代码中的许多局部变量和公共块的SAVE
语句。
解决方案是使用一个好的并行随机数生成器。该网站不是用于软件推荐,而是作为指针只搜索网络中的“并行prng”或“并行随机数生成器”。我亲自使用我已在https://stackoverflow.com/a/38263032/721644中指出的库。简单的网络搜索在https://jblevins.org/log/openmp中揭示了另一种简单的可能性。然后有许多更大,更复杂的库。