I read this post Puzzling performance difference between ifort and gfortran from 2012 and tried to run the code by myself:
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
(I changed a few lines so that the code will compile).
I compiled with ifort 19.1.3.304 and gfortran 10.2.0.
The ifort executable ran way faster than gfortran and included way more commands. According to the post, ifort 12.1.2.273 should have fixed the problem, but it doesn't seem to be fixed.
If I turn off vectorization on ifort, I get much better results on ifort but still worse than gfortran.
If I remove lines:
N=4
WRITE(*,*) IS_SQUARE(N)
I get much worse results on gfortran compared to the version with this lines.
I can keep going with some weird phenomena I have noticed but I mainly just want to know how this simple code can cause such big difference in the run time between the two compilers, and how can I avoid cases like this.
I compiled with -O3 on both and tried adding -no-vec to ifort. I'm open to other compilation flags.
UPDATE:
ifort example.f90 -O3 -o example_ifort
gfortran example.f90 -O3 -o example_gnu
run time for example_ifort is 3 sec while example_gnu is 1 sec