Inlining functions in Fortran
Asked Answered
O

2

8

In a Fortran project we use a binary search to find a desired value:

integer function binsearch(tab, el)
  implicit none

  real, intent(in) :: tab(:), el
  integer :: a, b, mid

  a = 1
  b = size(tab)

  do while (b - a > 1)
    mid = (a + b)/2
    if (el >= tab(mid)) then
      a = mid
    else
      b = mid
    endif
    ! if (el < tab(mid + 1)) exit ! BAD OPTIMIZATION !
  enddo

  binsearch = a
end function binsearch

Later on we simply use it

foo = binsearch(tab, el)

Unfortunately the surrounding routine is used so heavily, that the BAD OPTIMIZATION raises the total execution time by a half. So I considered inlining the function to diminish the call cost.

Is it possible to anyhow mark this function for inlining? In C there's the keyword inline which is a suggestion for the compiler - and is there anything like this in Fortran 2008?

I don't want to copy-paste this for the sake of the code clarity.

Over answered 22/2, 2017 at 8:18 Comment(3)
Please see https://mcmap.net/q/1310088/-inline-keyword-gfortranTantalite
In C the inline keyword does mostly nothing anyway.Spanjian
As mentioned in the URL given above, internal procedure is most conducive to inlining across all compilers. Binary search may not be the best, depending on table size and abilities of various compilers to vectorize linear search.Pompeii
L
5

It depends on the compiler. I can verify that this works for Cray and Intel Fortran compilers, but the statements are slightly different.

Cray compiler:

!dir$ forceinline :: frob

This would force the compiler to inline function frob. You'd place this immediately above the function definition.

Intel compiler:

!dir$ attributes forceinline :: frob

I do not see that gcc/gfortran currently has these options.

Manuals on both compilers cover this.

Lila answered 3/4, 2018 at 15:16 Comment(0)
G
11

In Fortran, there's no direct analogue to inline in C; it is always up to the compiler which functions are inlined. The most important thing is then to compile the code with a high optimization level to turn on aggressive inlining (e.g. -Ofast in gfortran, -fast in ifort). Also, you probably want to turn on "link-time optimization" (-flto in gfortran, -ipo in ifort), so that the compiler can inline functions from different source files at link-time if necessary.

However, there are ways to rewrite the code that increases the chance of inlining. One such way would be to explicitly mark the function as pure (i.e. a function without side-effects), as the implications of this makes it easier for the compiler to optimize the calls to it. In other words:

pure function binsearch(tab, el) result(r)
  real, intent(in) :: tab(:), el
  integer          :: r, a, b, mid

  ...
end function

if you could rewrite binsearch as a nested function inside whatever function you're using it from, it is very likely that the compile will either replace the function call to tab by the function body or a fast goto statement, even if you don't change the compilation options. In that case:

subroutine some_other_thing()
  ...

  ! Do the search
  i = binsearch(tab, el)

  ...

contains
  pure function binsearch(tab, el) result(r)
    real, intent(in) :: tab(:), el
    integer          :: r, a, b, mid

    ...
  end function
end subroutine
Gunslinger answered 22/2, 2017 at 8:57 Comment(3)
Is there any way I can verify whether the function has been inlined?Over
If you look at the map, if it has been inlined, you won't find an address for the function.Garrett
Note also that you can run pure subroutines as well. Functions and subroutines have some important differences when it comes to performance (namely that functions create copies of their input variables before working on them and subroutines do not).Gerhardt
L
5

It depends on the compiler. I can verify that this works for Cray and Intel Fortran compilers, but the statements are slightly different.

Cray compiler:

!dir$ forceinline :: frob

This would force the compiler to inline function frob. You'd place this immediately above the function definition.

Intel compiler:

!dir$ attributes forceinline :: frob

I do not see that gcc/gfortran currently has these options.

Manuals on both compilers cover this.

Lila answered 3/4, 2018 at 15:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.