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

将fortran代码划分为子例程的缺点及其对速度的影响?,fortran,gfortran,fortran90,intel-fortran,Fortran,Gfortran,Fortran90,Intel Fortran,我有一个大的有限元代码。我已经把它分成了子例程,这样它就可以被进一步分割和修改。我的问题是:为什么速度变慢了 当我把代码分成子例程时,速度变慢了 当参数的数量减少时(在子例程中以极小的计算量重新设置范围),它会变得更慢 有人能帮我一些建议吗,当fortran程序被划分成子例程时,如何优化它。特别是当在大循环中调用该子例程时。当一个大型单片代码被分成几个部分,每个部分可能被调用数百万次时,调用每个子例程或函数的开销通常是不可忽略的(无论使用何种特定编程语言),除非编译器(链接器)可以自动串联这些功

我有一个大的有限元代码。我已经把它分成了子例程,这样它就可以被进一步分割和修改。我的问题是:为什么速度变慢了

  • 当我把代码分成子例程时,速度变慢了
  • 当参数的数量减少时(在子例程中以极小的计算量重新设置范围),它会变得更慢

  • 有人能帮我一些建议吗,当fortran程序被划分成子例程时,如何优化它。特别是当在大循环中调用该子例程时。

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

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

    我怀疑代码缓存可以提高性能,因此,如果相关例程分布在内存中,“可能”会导致性能下降。 识别与缓存相关的延迟很难实现

    如果这是一种解释,那么在链接时更改正在添加的例程的顺序可能会显示一些更改。这种可能方法的示例包括ddotp近方程简化和daxpy近方程反向替换可能是有效的

    有效地,这种方法是在调用例程附近链接内部循环例程。在开发代码时,通常是这样。 您尚未说明链接订单的方法;基于这种假设,按字母顺序排列是一种糟糕的方法。 FEM代码更好地描述为多段文字,所以这种方法应该是可用的。我曾尝试过多个版本的高使用率实用程序,将它们放入代码中,例如用于特征子空间迭代或直接积分解决方案的重复方程解算器,其中内部循环占解决方案时间的很大比例

    使用不同内存速度/带宽或缓存大小的处理器进行实验可以提供一个有趣的比较。 然而,将内存管理缓存到分区阵列的策略应该比尝试链接顺序更有效

    另一个问题与编译器是否优化例程调用或是否内联一些琐碎的例程有关。您尚未指明编译选项或编译器,以确定这是否有可能


    我希望这个答案提供了一些可能需要进一步调查的领域,但没有对您的问题提供明确的解释。

    没有代码,任何人都无法帮助您。这个问题基本上无法回答,我投了反对票。过程间优化应能消除过程调用的许多性能影响。内部过程为编译器提供了更多的机会,但不需要过度使用。至少25年来,基准包括了这方面的测试。为了避免依赖这种优化,您必须本地化需要在过程内部切换、展开和阻塞的可向量化代码和循环。折叠优化(openmp或串行)可能无法通过过程调用实现。是否使用内联?如果您知道它在哪里花费了更多时间,那么这将是了解原因以及如何修复它的一个很好的开始。