将fortran代码划分为子程序及其对速度的影响的缺点?

时间:2018-06-11 19:08:11

标签: fortran gfortran fortran90 intel-fortran

我有一个大的FEM代码。我把它分成了子程序,因此可以进一步划分和更改。我的问题是:为什么速度变慢。

  1. 当我将代码分成子程序时,速度变慢了
  2. 当参数数量减少时,它变得更慢(在子程序内重新安排计算极小)。
  3. 有人可以帮我提一些建议,如何将fortran程序划分为子程序时优化它。特别是当在一个大循环中调用该子程序时。

2 个答案:

答案 0 :(得分:0)

当一个大的单片代码被分成几个部分,每个部分被调用数百万次时,调用每个子程序或函数的开销成本通常是不可忽略的(无论使用何种特定的编程语言),除非编译器(链接器)可以自动内联这些函数。我怀疑编译器缺少内嵌是你在代码中观察到的显着减速的根源。关于你的问题2,我无法理解。也许最小的工作示例代码会有所帮助,正如@VladimirF和@HighPerformanceMark建议的那样。

答案 1 :(得分:0)

识别原因可能很困难,因为可以识别此类问题的发生。

我怀疑代码的缓存可以提高性能,因此如果相关例程遍布整个内存,那么“可能”会有性能损失。 识别缓存相关的延迟很难实现。

如果这是一个解释,那么更改链接时添加的例程的顺序可能会显示一些变化。这种可能的方法的例子包括ddotp近似方程减少和daxpy近似方程后替换可能是有效的。

实际上,这种方法是将内循环例程链接到调用例程附近。在开发代码时,通常就是这种情况。 您尚未表明您关联订单的方法;按字母顺序排列将是一种基于这种假设的不良方法。 FEM代码更好地描述为多晶,因此这种方法应该是可用的。我已经尝试了多个版本的高使用率实用程序,将它们放在代码中,例如用于特征子空间迭代的重复方程求解器或直接积分解决方案,其中内部循环占解决时间的很大比例。

尝试使用具有不同内存速度/带宽或缓存大小的处理器可以提供有趣的比较。 但是,将内存管理缓存到分区数组的策略应该比试验链接顺序更有效率。

另一个问题涉及编译器是否优化了例程调用,或者它是否内联了一些简单的例程。您尚未指明编译选项或编译器以确定是否可能。

我希望这个答案提供一些可能进一步调查的领域,同时没有为您的问题提供明确的解释。