5

我习惯性地编写具有很多功能的代码,我发现它使代码更清晰。但是现在我正在用 Fortran 编写一些需要非常高效的代码,我想知道过度使用函数是否会减慢它的速度,或者编译器是否会弄清楚发生了什么并进行优化?

我知道在 Java/Python 等中每个函数都是一个对象,因此创建大量函数需要在内存中创建它们。我也知道在 Haskell 中,这些功能被简化为彼此,所以在那里几乎没有什么区别。

有人知道 Fortran 的情况吗?使用意图/纯函数/声明更少的局部变量/其他有什么区别吗?

4

4 回答 4

9

对于基于堆栈的语言(如 Fortran),函数调用会带来性能成本。他们必须添加到堆栈等。

因此,如果可能的话,大多数编译器都会尝试积极地内联函数调用。大多数情况下,编译器会正确选择是否内联程序中的某些函数。

这种自动内联过程意味着编写函数(完全)没有额外的成本。

这意味着您应该尽可能干净和有条理地编写代码,并且编译器很可能会为您进行这些优化。更重要的是,解决问题的总体策略比担心函数调用的性能最有效。

于 2010-07-09T16:47:09.130 回答
2

只需以最简单且结构最完善的方式编写代码,然后在编写和测试代码后,您可以对其进行分析,以查看是否有任何热点需要优化。只有在这一点上,您才应该关注微优化,如果您的编译器正在完成它的工作,这甚至可能没有必要。

于 2010-07-09T16:36:48.407 回答
1

I've just spent all morning tuning an app consisting of mixed C and Fortran, and of course it uses a lot of functions. What I found (and what I usually find) is not that functions are slow, but that certain function calls (and very few of them) don't really have to be done at all. For example, clearing memory blocks, just to be neat, but doing it at high frequency.

This is not a function of language, and not really a function of inlining either. Function calls could be free and you would still have the problem that the call tree tends to be more bushy than necessary. You need to find out where to prune it. This is the "profiling" method I rely on.

Whatever you do, find out what needs to be fixed. Don't Guess. Many people don't think of this kind of question as guessing, but when they find themselves asking "Will this work, will that help?", they're poking in the dark, rather than finding out where the problems are. Once they know where the problems are, the fix is obvious.

于 2010-07-09T18:52:53.253 回答
0

通常 Fortran 中的子程序/函数调用的开销很小。虽然语言标准没有指定参数传递机制,但典型的实现是“通过引用”,因此不涉及复制,只设置一个新过程。在大多数现代架构上,这几乎没有开销。选择好的算法通常比微优化重要得多。

调用 be quick 的一个例外可能是编译器必须创建临时数组,例如,如果实际参数是不连续的数组子部分,而被调用的过程参数是普通的连续数组。假设虚拟参数是维度 (:)。使用维度数组 (:) 调用它很简单。如果您在调用中请求非单位步幅,例如数组 (1:12:3),则该数组是不连续的,编译器可能需要创建一个临时副本。假设实际参数是维度 (:,:)。如果调用有数组 (:,j),则子数组是连续的,因为在 Fortran 中,第一个索引在内存中变化最快,不需要副本。但是数组 (i,:) 是不连续的,可能需要一个临时副本。

一些编译器可以选择在需要临时数组副本时向您发出警告,以便您可以根据需要更改代码。

于 2010-07-09T17:22:07.763 回答