#performance #module #fortran #fortran90
#Производительность #модуль #fortran #fortran90
Вопрос:
Я конвертирую код F77 в F90 и пытаюсь избавиться от неявного объявления и включений.
В частности, у меня есть подпрограмма (часто вызываемая)
подпрограмма :
SUBROUTINE GRADE(NIE,NJE,NKE,IDEW,IDNS,IDTB,FI,FIF,GRX,GRY,GRZ)
USE module_dec
USE module_geom_common
IMPLICIT NONE
REAL :: FI(NXYZA),FIF(NXYZA)
REAL :: GRX(NXYZA),GRY(NXYZA),GRZ(NXYZA)
REAL :: BN(NXYZA),BE(NXYZA),BT(NXYZA)
REAL :: FIE
INTEGER :: NIE,NJE,NKE,IDEW,IDNS,IDTB
INTEGER :: I,J,K
! Declaration of the variables used in file.inc
REAL :: ARX,ARY,ARZ
REAL :: AKX,AKY,AKZ
REAL :: ARE,ARE2,ARKSI2
REAL :: FXE,FXW
INTEGER :: INE
REAL :: DELN,DELNR
DO 30 K=2,NKE
DO 30 I=2,NIE
DO 30 J=2,NJE
INCLUDE "file.inc"
FIE=FI(INP)*FXW FI(INE)*FXE
BE(INP)= FIE*ARX
BN(INP)= FIE*ARY
BT(INP)= FIE*ARZ
30 CONTINUE
DO 31 K=2,NKE
DO 31 I=2,NIE
DO 31 J=2,NJE
INP=LK(K) LI(I) J
GRX(INP)=GRX(INP) BE(INP)
GRY(INP)=GRY(INP) BN(INP)
GRZ(INP)=GRZ(INP) BT(INP)
GRX(INP IDEW)=GRX(INP IDEW)-BE(INP)
GRY(INP IDEW)=GRY(INP IDEW)-BN(INP)
GRZ(INP IDEW)=GRZ(INP IDEW)-BT(INP)
31 CONTINUE
и file.inc
INP=LK(K) LI(I) J
INE=INP IDEW
INS=INP-IDNS
INB=INP-IDTB
INBS=INB-IDNS
FXE=FIF(INP)
FXW=1.-FXE
DXS=.5*(X(INP)-X(INS) X(INB)-X(INBS))
DYS=.5*(Y(INP)-Y(INS) Y(INB)-Y(INBS))
DZS=.5*(Z(INP)-Z(INS) Z(INB)-Z(INBS))
DXT=.5*(X(INP)-X(INB) X(INS)-X(INBS))
DYT=.5*(Y(INP)-Y(INB) Y(INS)-Y(INBS))
DZT=.5*(Z(INP)-Z(INB) Z(INS)-Z(INBS))
ARX=DYS*DZT-DYT*DZS
ARY=DZS*DXT-DZT*DXS
ARZ=DXS*DYT-DXT*DYS
ARE2=ARX**2 ARY**2 ARZ**2
AKX=XC(INE)-XC(INP)
AKY=YC(INE)-YC(INP)
AKZ=ZC(INE)-ZC(INP)
ARKSI2=AKX**2 AKY**2 AKZ**2
При этом время выполнения моей программы составляет 12 секунд
Когда я перемещаю объявление переменных, присутствующих в файле.inc’ в модуле,
MODULE module_geom_common
REAL :: ARX,ARY,ARZ
REAL :: AKX,AKY,AKZ
REAL :: ARE,ARE2,ARKSI2
REAL :: FXE,FXW
INTEGER :: INE
REAL :: DELN,DELNR
END MODULE module_geom_common
Сейчас у меня время выполнения составляет 13 секунд.
Я компилирую с помощью ifort, но я наблюдаю то же самое с gfortran.
Я не понимаю, почему я медленнее. Это потому, что переменные, объявленные внутри модуля, будут помещены в другое место в памяти, что приведет к пропуску кэша или чему-то подобному?
Есть ли способ преодолеть это без использования include ?
РЕДАКТИРОВАТЬ: я отредактировал свой вопрос, чтобы дать более подробную информацию.
Комментарии:
1. Локальные переменные могут быть размещены в стеке или даже в регистрах, тогда как переменные модуля распределяются статически. Если ваш код вызывает какие-либо процедуры, компилятор должен предположить, что к переменным модуля можно получить доступ или изменить, тогда как локальные переменные, отсутствующие в списках аргументов, не могут — это может повлиять на оптимизацию. Не видя полного примера, трудно строить дальнейшие предположения.
2. Как вы определяете время?