2017-02-22 3 views
0

Dans un projet Fortran, nous utilisons une recherche binaire pour trouver une valeur souhaitée:fonctions inline dans Fortran

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 

Plus tard nous utilisons simplement

foo = binsearch(tab, el) 

Malheureusement, la routine environnante est utilisé si lourdement , que le BAD OPTIMIZATION augmente le temps d'exécution total de moitié. J'ai donc considéré la fonction pour diminuer le coût de l'appel.

Est-il possible de marquer de toute façon cette fonction pour inline? En C il y a le mot-clé inline qui est une suggestion pour le compilateur - et y a-t-il quelque chose comme ça dans Fortran 2008?

Je ne veux pas copier-coller ceci pour la clarté du code.

+1

S'il vous plaît voir http://stackoverflow.com/questions/6763402/inline-keyword-gfortran – solalito

+0

En C le mot-clé 'inline' ne surtout rien de toute façon. –

+0

Comme mentionné dans l'URL donnée ci-dessus, la procédure interne est la plus propice à l'inlining à travers tous les compilateurs. La recherche binaire peut ne pas être la meilleure, en fonction de la taille de la table et des capacités des différents compilateurs pour vectoriser la recherche linéaire. – tim18

Répondre

2

Dans Fortran, il n'y a pas d'analogue direct à inline en C; il appartient toujours au compilateur quelles fonctions sont en ligne. La chose la plus importante est alors de compiler le code avec un niveau d'optimisation élevé pour activer l'inline (par exemple -Ofast dans gfortran, -fast dans ifort). En outre, vous souhaitez probablement activer "optimisation de liaison" (-flto dans gfortran, -ipo dans ifort), de sorte que le compilateur peut intégrer des fonctions de différents fichiers source au moment de la liaison si nécessaire.

Toutefois, il existe des moyens de réécrire le code qui augmente les chances de l'inline. Un tel moyen consisterait à marquer explicitement la fonction sous la forme pure (c'est-à-dire une fonction sans effets secondaires), étant donné que les implications de cette opération facilitent l'optimisation des appels par le compilateur. En d'autres termes:

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

    ... 
end function 

si vous pouvez réécrire binsearch en fonction imbriquée à l'intérieur quelle que soit la fonction que vous utilisez à partir, il est très probable que la compilation sera soit remplacer l'appel de fonction à tab par le corps de la fonction ou une instruction rapide goto, même si vous ne modifiez pas les options de compilation. Dans ce cas:

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 
+0

Est-il possible de vérifier si la fonction a été insérée? – marmistrz

+1

Si vous regardez la carte, si elle a été inline, vous ne trouverez pas d'adresse pour la fonction. – cup