我在本地 Windows 计算机和集群上运行相同的 Fortran 代码。
代码如下:
program mwe
use omp_lib
implicit none
integer :: indx
integer :: indy
integer :: indz
integer :: total_z = 1000000
integer :: total_x = 200
integer :: total_y = 100
real, allocatable :: output(:,:), grid_x(:), grid_y(:)
real :: startTime, midTime, totalTime
allocate(output(total_x, total_y))
allocate(grid_x(total_x))
allocate(grid_y(total_y))
do indx = 1, total_x
grid_x(indx) = indx * 2
end do
do indy = 1, total_y
grid_y(indy) = indy / 3
end do
output = 0.0
startTime = omp_get_wtime()
do indz = 1,total_z
do indy = 1,total_y
!$omp parallel do default(private) shared(indy, total_y, indz, total_z, total_x, output, startTime)
do indx = 1,total_x
output(indx,indy) = output(indx,indy) + grid_x(indx)/grid_y(indy)
if ((mod(indz, 100000) .eq. 0) .and. (indx .eq. 1) .and. (indy .eq. 1)) then
midTime = omp_get_wtime()
write(*,"(A,F15.1,A)") "Total time elapsed",midTime-startTime," seconds."
end if
end do
!$omp end parallel do
end do
end do
end program
在 Windows 上我将代码编译为:
ifort /O2 /c /Qopenmp main.f90
ifort /o main.out /O2 /Qopenmp main.f90 /link /STACK:999999999,999999999
main.out
输出为:
总时间经过119.4秒。
总时间经过237.8秒。
总时间经过357.7秒。
总时间经过474.1秒。
总时间经过588.7秒。
总时间经过730.1秒。
总时间经过 873.0 秒。
总时间经过1015.4秒。
总时间经过1159.6秒。
在集群(linux)上我将代码编译为:
#!/bin/bash
#SBATCH -e error_file.err
#SBATCH -p common
#SBATCH -c 40
#SBATCH --job-name==mwe
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
export OMP_STACKSIZE=512mb
source /opt/apps/rhel8/intel-2020/compilers_and_libraries/linux/bin/compilervars.sh intel64
ifort -O2 -c -qopenmp main.f90
ifort -o main.out -O2 -qopenmp main.f90
./main.out
输出为:
总时间已过 0.0 秒。
总时间已过 0.0 秒。
总时间已过 128.0 秒。
总时间已过 128.0 秒。
总时间已过 128.0 秒。
总时间已过去 256.0 秒。
总时间已过去 256.0 秒。
总时间已过去 384.0 秒。
总时间已过去 384.0 秒。
总时间已过去 384.0 秒。
这是 Linux 上
ifort
的编译器错误。 omp_get_wtime()
是一个 double precision
函数,并且您将其输出分配给 real
变量:这应该没问题,在 Fortran 中像往常一样进行隐式转换,但是 ifort
在这里搞砸了。
声明
double precision :: startTime, midTime, totalTime
解决了问题。
此外,您的 MRE 中有一个不相关的错误:
grid_x
和 grid_y
应在 OpenMP 区域中声明为 shared
。
您正在计算两个大数的差异。但使用默认的实数,您无法获得足够的精度。
Compare
Total time elapsed 1717144796.8 1717144796.7 seconds.
Total time elapsed 1717144797.0 1717144796.7 seconds.
Total time elapsed 1717144797.1 1717144796.7 seconds.
Total time elapsed 1717144797.2 1717144796.7 seconds.
Total time elapsed 1717144797.4 1717144796.7 seconds.
Total time elapsed 1717144797.5 1717144796.7 seconds.
Total time elapsed 1717144797.6 1717144796.7 seconds.
Total time elapsed 1717144797.8 1717144796.7 seconds.
Total time elapsed 1717144797.9 1717144796.7 seconds.
Total time elapsed 1717144798.1 1717144796.7 seconds.
Total time elapsed 1717144798.2 1717144796.7 seconds.
Total time elapsed 1717144798.3 1717144796.7 seconds.
Total time elapsed 1717144798.5 1717144796.7 seconds.
Total time elapsed 1717144798.6 1717144796.7 seconds.
Total time elapsed 1717144798.7 1717144796.7 seconds.
Total time elapsed 1717144798.9 1717144796.7 seconds.
双精度