2013-01-18 64 views
-1

有什么理由相信fortran内部函数比外部函数表现更好?内部函数的性能

例如

subroutine foo(x,y) 
    real :: x 
    x = bar(y) 
    return 
    contains 
    real function bar(x) 
     real :: x 
     bar = x*x 
     return 
    end function bar 
end subroutine foo 

VS

subroutine foo(x,y) 
    real :: x 
    real :: bar 
    x = bar(y) 
    return 
end subroutine foo 

real function bar(x) 
    real :: x 
    bar = x*x 
    return 
end function bar 

例如,不内部单元允许编译器内联等某种宏代码?

+0

内联函数适合内联。声明函数也是如此。 –

回答

1

我不认为有任何一般原因认为Fortran内部函数会比外部函数执行更好。通过一般原因我的意思是适用于所有平台上的所有符合Fortran标准的编译器。所以我不相信在表演的基础上,人们可以表达一个普遍的(同样的意义上)内部的外部功能。

我会走得更远,我不认为语言标准(其中任何一个标准)中有很多内容可以很好地支持关于实现相同功能的各种方法的相对性能的争论。因此,举另一个例子,我认为标准不会允许人们争辩说,明确的do循环应该超过等效的基于数组的语法表达式。或者反之亦然。

但是我确实认为可能会有某些原因,特定于编译器版本和/或平台,因此出于性能考虑,宁愿选择另一种方法。例如,上次我在英特尔处理器的MS Windows上测试英特尔Fortran编译器(可能是v11.something)时,我得出结论,明确的do循环通常会超出等效的数组语法表达式。由于性能往往是Fortran程序员的一个关键问题,因此在编译器开发时,我们应当监视各种方法的性能,而不要陷入过时的性能观念之中。

与往常一样,在这个游戏中,硬数据胜过争论。计划表现是一门实验科学。

+0

我看不到任何理由相信外部单位会超过内部单位。使用内部程序单元,编译器可以优化调用,从而节省分配和销毁堆栈帧的时间...... – mgilson

+0

作为一个方面说明,如果我编译的内部版本与'gfortran'不同优化('-O0'和'-O3'),当用'nm'进行检查时,我得到了不同的符号表。这是否意味着编译器内联子单元? – mgilson

1

对于可能引起争议的事情...有一个暗示,内部程序“执行”比标准中的外部程序更好,但并不意味着您(可能)的含义。

内部程序和模块程序获得自动显式接口。这要求编译器检查每个过程引用的某些方面,并使大多数正式编译器能够检查许多其他方面。通过外部程序实现相同级别的检查需要手动提供易于出错的界面。

在一般情况下,自动显式接口产生的程序健壮性好处(非常多的一种表现形式)消除了任何“执行速度”性能考虑因素,这些日子最好归结为“它取决于“/”你需要测量以找出“/”对于任何体面的编译器来说可能没有区别“。

在这种情况下,将bar(和foo)作为模块过程可能会更好 - 因为它消除了与foo无关的主机变量关联,并且可以独立测试bar。

程序类型的选择应基于源代码的技术要求(外部程序仍然存在于现代Fortran代码库中的正确理由,但它们不是典型的),然后是鲁棒性以及模块与内部程序可能提供的源代码的清晰度。如果您需要考虑此决定中的执行速度性能,那么您的编译器将被破坏。

+0

在我的用例中,'foo'已经是一个模块过程。我试图决定是否将'bar'作为一个内部程序,一个模块程序在同一模块中,或者作为我们自定义预处理器中的一个宏。该例程位于代码的非常性能关键部分的中心。后一种选择是我最不喜欢的,因为美观和可调试的原因,但我不希望在代码中创建一个瓶颈,而之前我没有更新它来使用f90构造。 – mgilson

+0

你提到的三个选项都不是外部过程 - 所以你的问题与你的用例无关。对于该用例,您需要使用代表生产运行的编译器选项和输入数据进行测量。我仍然认为任何差异对于具有合适优化设置的体面编译器来说都是无关紧要的。 – IanH