问题描述
我在 2012 年阅读了这篇文章 Puzzling performance difference between ifort and gfortran 并尝试自己运行代码:
PROGRAM PERFECT_SQUARE
IMPLICIT NONE
INTEGER*8 :: N,M,NTOT
LOGICAL :: IS_SQUARE
N=4
WRITE(*,*) IS_SQUARE(N)
NTOT = 0
DO N = 1,1000000000
IF (IS_SQUARE(N)) THEN
NTOT = NTOT + 1
END IF
END DO
WRITE (*,*) NTOT ! should find 31622 squares
END PROGRAM
LOGICAL FUNCTION IS_SQUARE(N)
IMPLICIT NONE
INTEGER*8 :: N,M
! check if negative
IF (N .LT. 0) THEN
IS_SQUARE = .FALSE.
RETURN
END IF
! check if ending 4 bits belong to (0,1,4,9)
M = IAND(int(N,kind(8)),int(15,kind(8)))
IF (.NOT. (M .EQ. 0 .OR. M .EQ. 1 .OR. M .EQ. 4 .OR. M .EQ. 9)) THEN
IS_SQUARE = .FALSE.
RETURN
END IF
! try to find the nearest integer to sqrt(n)
M = DINT(SQRT(DBLE(N)))
IF (M**2 .NE. N) THEN
IS_SQUARE = .FALSE.
RETURN
END IF
IS_SQUARE = .TRUE.
RETURN
END FUNCTION
(我更改了几行以便代码可以编译)。
我用 ifort 19.1.3.304 和 gfortran 10.2.0 编译。
ifort 可执行文件的运行速度比 gfortran 快得多,并且包含了更多的命令。根据帖子,ifort 12.1.2.273应该已经修复了问题,但似乎没有修复。
如果我关闭 ifort 上的矢量化,我会在 ifort 上获得更好的结果,但仍然比 gfortran 差。
如果我删除行:
N=4
WRITE(*,*) IS_SQUARE(N)
与使用此行的版本相比,我在 gfortran 上获得了更糟的结果。
我可以继续处理我注意到的一些奇怪现象,但我主要只是想知道这段简单的代码如何导致两个编译器之间的运行时间出现如此大的差异,以及如何避免此类情况。
>我在两者上都使用 -O3 进行编译,并尝试将 -no-vec 添加到 ifort。我对其他编译标志持开放态度。
更新:
ifort example.f90 -O3 -o example_ifort
gfortran example.f90 -O3 -o example_gnu
example_ifort 的运行时间为 3 秒而 example_gnu 的运行时间为 1 秒
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)