У меня довольно большой код (> 6000 строк), с проблемой, которую я пытаюсь проиллюстрировать следующим очень упрощенным фрагментом:
program TestFortran
implicit none
real, parameter :: eps = 1d-30
real :: res
real :: tmp
call TestInitialisation(res,tmp)
if (res>0 .and. res <eps) then
write(*,*) "res is small but not zero and tmp = ", tmp
res = 0d0
else
write(*,*) "res is zero and tmp = ", tmp
end if
contains
subroutine TestInitialization(output,out2)
real,intent(out) :: output
real,intent(out) :: out2
real :: origa(10,10)
real :: copya(10,10)
origa = 0d0
copya = origa
call TIS1(copya,output,out2)
end subroutine TestInitialization
subroutine TIS1(arr2d,ret,out2)
real,intent(in) :: arr2d(:,:)
real,intent(out) :: ret
real,intent(out) :: out2
integer :: ii
do ii = 1,size(arr2d,2)
call TIS2(arr2d(:,ii),ii,ret,out2)
if (ret > 0) then
exit
end if
end do
end subroutine TIS1
subroutine TIS2(arr1d,jj,ret,out2)
real,intent(in) :: arr1d(:)
real,intent(out) :: ret
real,intent(out) :: out2
integer :: ii
integer,intent(in):: jj
do ii = 1,size(arr1d)
ret = arr1d(ii)
out2 = real(jj)
if (ret > 0) then
out2 = -1d0
exit
end if
end do
end subroutine TIS2
end program TestFortran
Реальная программа работает должным образом в режиме отладки. Однако, когда в режиме выпуска (Visual Studio 2017 с Intel Compiler 2017), переключите / O3, значение res
- просто мусор (как 1.0831d-273, однако я не уверен, стоит ли доверять проводнику переменных при отладке оптимизированного кода) , Я не мог воссоздать ситуацию с приведенным выше примером, он просто служит иллюстрацией (переменная tmp
предназначена для того, чтобы не просто оптимизировать все это). Если я добавлю write(*,*) "res in TIS2 =",res
в подпрограмму TIS2
в коде реальной программы , результат будет правильным, но этого не требуется (особенно из-за снижения скорости).
Я проверил различные комбинации флагов компилятора; то есть следующее:
/ debug: full / O2 / Qinit: snan / Qinit: arrays / fpe: 0 / Qipo / traceback
/ check: uninit / arch: SSE3 / real_size: 64 / fp: fast = 2 / Qvec-порог: 60 / рекурсивный
У кого-нибудь есть подсказки или комментарии по этому поводу?