Я прочитал этот пост Непонятная разница в производительности между ifort и gfortran с 2012 года по попытался запустить код самостоятельно:
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 секунду.
int(N, kind(8))
? Я думаю, вы имеете в видуkind=8
илиkind(m)
. Написаниеint(n,kind(8))
— это очень странный способ написанияint(n)
с точно таким же значением. - person francescalus   schedule 09.03.2021