在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稍后我们将简单地使用它
foo = binsearch(tab, el)不幸的是,周围的例程被大量使用,以至于BAD OPTIMIZATION将总执行时间提高了一半。因此,我考虑内联函数以减少调用成本。
是否可以将此函数标记为内联?在C中有关键字inline,这是对编译器的建议-在Fortran2008中有类似的东西吗?
为了代码的清晰度,我不想复制-粘贴。
发布于 2018-04-03 23:16:58
这取决于编译器。我可以验证这是否适用于Cray和英特尔Fortran编译器,但语句略有不同。
Cray编译器:
!dir$ forceinline :: frob这将强制编译器内联函数frob。你应该把它放在函数定义的正上方。
英特尔编译器:
!dir$ attributes forceinline :: frob我没有看到gcc/gfortran目前有这些选项。
两个编译器的手册都涵盖了这一点。
发布于 2017-02-22 16:57:21
在Fortran中,没有直接类似于C中的inline;它总是由编译器决定内联哪些函数。然后,最重要的事情是用高优化级别编译代码,以打开积极的内联(例如,gfortran中的-Ofast,ifort中的-fast )。此外,您可能希望打开“链接时优化”( gfortran中的-flto,ifort中的-ipo ),以便编译器可以在必要时在链接时内联来自不同源文件的函数。
但是,有一些方法可以重写代码,从而增加内联的机会。一种这样的方法是显式地将函数标记为pure (即没有副作用的函数),因为这意味着编译器更容易优化对它的调用。换句话说:
pure function binsearch(tab, el) result(r)
real, intent(in) :: tab(:), el
integer :: r, a, b, mid
...
end function如果您可以将binsearch重写为使用它的任何函数中的嵌套函数,则即使您不更改编译选项,编译器也很可能会用函数体或快速goto语句替换对tab的函数调用。在这种情况下:
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 subroutinehttps://stackoverflow.com/questions/42386065
复制相似问题