如果或函数指针在fortran中

时间:2012-03-22 19:40:28

标签: performance fortran

因为它与Fortran如此常见,我正在编写一个大规模并行的科学代码。在我的代码的开头,我读了我的配置文件,告诉我我想使用哪种类型的解算器。现在这意味着在子程序中(在主要运行期间)我有

if(solver.eq.1)then
  call solver1()
elseif(solver.eq.2)then
  call solver2()
else
  call solver3()
endif

编辑以避免一些混淆:这个if在我的时间积分循环中,我有一个在3个嵌套循环中。

现在我的问题是,使用函数指针不是更有效,因为solver变量在执行期间不会改变,除非在初始化过程中。

显然,函数指针是F2003。只要我使用gfortran 4.6,这应该不是问题。但是我主要使用BlueGene P,有一个f2003编译器,所以我想它也可以在那里工作,虽然我在网上找不到任何确凿的证据。

4 个答案:

答案 0 :(得分:3)

对Fortran一无所知,这是我的答案:分支的主要问题是CPU可能无法推测性地执行代码。为了缓解这个问题,引入了分支预测(在现代CPU中非常复杂)。

通过函数指针的间接调用可能是CPU预测单元的问题。如果它无法预测实际调用的位置,这将使管道停滞。

我非常确定CPU会正确预测您的分支将始终被采用或不采用,因为它是一个简单的预测案例。

也许CPU可以跨间接调用进行推测,也许它不能。这就是为什么你需要测试哪个更好。

如果不能,你肯定会注意到你的基准。

此外,也许您可​​以将内部循环中的if测试提升,因此不会经常调用它。这将使分支的实际性能无关紧要。

答案 1 :(得分:2)

如果您只打算在初始化时使用函数指针一次,并且您在BlueGene上运行代码,那么您对效率误导的关注不是您的问题吗?通常,任何有效的初始化都可以,如果需要1秒而不是1毫秒,它可能会对总执行时间产生0影响。

代码初始化例程,清晰,易于修改,等等。

编辑

我的猜测是使用函数指针而不是当前代码对执行速度没有影响。但这只是一个(可能是受过教育的)猜测,我对你在这个问题上收集的任何数据都非常感兴趣。

答案 2 :(得分:1)

如果求解器例程采用非平凡的运行时,那么IF语句的平凡运行时可能并不重要。如果sovler例程具有与IF语句类似的runtine,则总运行时间非常短,那么为什么要关心呢?这似乎是一种不太可能得到回报的优化。

运行时优化的第一条规则是对代码进行分析,看看哪些部分正在消耗运行时。否则,您可能会优化不重要的部分,这些部分将无法实现。

为了它的价值,其他人最近也有一个非常相似的问题:Fortran Subroutine Pointers for Mismatching Array Dimensions

答案 3 :(得分:1)

经过简短的搜索,我无法找到问题的答案,所以我自己运行little benchmark(请参阅this link了解Makefile和依赖项)。基准包括:

  • 绘制随机数以选择方法 a b c ,它们都会对其单个整数参数执行简单的添加
  • 使用过程指针或if-statements
  • 调用所选方法1亿次
  • 重复以上5次

[Api Keys](#tag/Api%20Keys) gfortran 4.8.5的结果是:

CPU E5-2630 v3 @ 2.40GHz

换句话说,没有太大的性能差异!