0

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

nadavhalahmi
  • 101
  • 6
  • 1
    Not related to your problem, but what are you meaning with `int(N, kind(8))`? I think you mean `kind=8`, or `kind(m)`. Writing `int(n,kind(8))` is a very strange way of writing `int(n)` with exactly the same meaning. – francescalus Mar 09 '21 at 16:18
  • 3
    "ran way faster", "included way more commands", "get much worse" don't really mean too much. What are the exact command line options used with each compiler? – steve Mar 09 '21 at 16:45
  • francescalus- I did what compiled to me.. this is just an example code. steve- I tried many options, but lets discuss first the simple ones: 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 – nadavhalahmi Mar 10 '21 at 07:32

0 Answers0