I am writing some simulation code (almost) from scratch and want to use OOP features from fortran to keep it easier to maintain. I've learned in a fortran workshop, that one should be carefull when using OOP features within performance critical parts of the code.
My naive first approach (ignoring the warning) would be the following snippet. The background is the calculation of a system energy which needs an interaction potential. For this potential, I use an abstract type (potential). All users can then add their own potentials as extensions and define a keyword that is used to allocate their potential. The energy calculation in the main program does not change.
module system_mod
implicit none
type, abstract :: potential
contains
procedure(init), deferred :: init
procedure(eval), deferred :: eval
end type
type, extends(potential) :: my_potential
! some parameters
contains
procedure :: init => init_my_potential
procedure :: eval => eval_my_potential
end type
! omitted: other extensions of 'potential'
! and abstract interface of potential
type :: system
! some components
class(potential), allocatable :: pair_potential
contains
procedure :: init ! subroutine, which is used to allocate pair_potential depending on a passed keyword
end type
contains
! implementation of all routines
end module system_mod
program main
use system_mod, only: potential, my_potential, system
implicit none
character(len=3) :: keyword !
integer :: i
real :: coordinates(n,3) ! n is a huge number
real :: energy, system_energy
type(system) :: test_system
call test_system%init ( keyword )
! keyword tells which of the extensions of 'potential' is allocated
do i = 1, n
energy = test_system%pair_potential%eval ( ... )
system_energy = system_energy + energy
end do
end program
I think my main problem concerning the performance is that I don't get what the compiler actually does at compile time and which things are done at run time.
So my questions are:
- How or when does the compiler check, which instance of 'eval' to use?
- When the keyword is known at compile time, is there a type check in every iteration of the loop?
- Would it be better to, for example, use a procedure pointer in the main program, and associate it at the beginning to the according 'eval' procedure?
Thank you very much in advance!
It has a virtual table of procedures that are possible to be called for the binding for all extended types and decides in run-time from this table.
Setting keyword may not help, it depends on how much the compiler is clever. I would use
type
instead ofclass
if the type is known at the compile time. This is very likely to skip the vtable look-up.The procedure pointer will affect the flow of the instructions too, although you may save some part of the vtable look-up. This really depends on the internals and is worth a try and some performance measurement.