有关提高Fortran代码性能的提示和技巧

作为我博士的一部分研究,我正致力于大气和海洋环流数值模型的开发.这些涉及在约10 ^ 4个网格点的数量上解决PDE的系统,超过~10 ^ 4个时间步长.因此,在MPI上运行数十个CPU时,典型的模型仿真需要数小时到几天才能完成.当然,尽可能提高模型效率很重要,同时确保结果是逐字节相同的.

虽然我对Fortran编程感到非常满意,并且我意识到使代码更高效的一些技巧,但我觉得还有待改进的空间,以及我不知道的技巧.

目前,我确保尽可能少地使用分区,并尽量不使用文字常量(我很早就教过这样做,例如在实际计算中使用半= 0.5而不是0.5),使用少量超越函数尽可能等

还有哪些其他性能敏感因素?目前,我想知道一些:

1)数学运算的顺序是否重要?例如,如果我有:

a=1E-7 ; b=2E4 ; c=3E13
d=a*b*c

会根据乘法的顺序以不同的效率进行评估吗?如今,这必须是特定于编译器的,但有一个直接的答案吗?我注意到基于订单(精度限制)得到(稍微)不同的值,但这会影响效率吗?

2)将多个(例如几十个)数组作为参数传递给子程序而不是从子程序中的模块访问这些数组?

3)Fortran 95构造(FORALL和WHERE)与DO和IF相比?我知道这些问题在90年代很重要,因为代码矢量化是一件大事,但现在有没有区别现代编译器能够对显式DO循环进行矢量化? (我在工作中使用PGI,Intel和IBM编译器)

4)将数字增加到整数幂乘以?例如.:

b=a**4

要么

b=a*a*a*a

我被教导要尽可能使用后者.这会影响效率和/或精度吗? (也可能是编译器依赖)

请讨论和/或添加有关提高Fortran代码效率的任何技巧和提示.还有什么呢?如果您知道上述每个编译器与此问题相关的具体内容,请同时包含该内容.

补充:请注意,我本身没有任何瓶颈或性能问题.我问的是,在操作意义上是否存在优化代码的一般规则.

谢谢!

你有关于该做什么的先验想法,其中一些可能实际上有所帮助,
但最大的回报是在后验分析中.
(补充:换句话说,将* b * c换成不同的顺序可能会节省几个周期(我怀疑),而与此同时你不知道你不会因为花费1000的东西而失明没有充分理由的周期.)

无论你如何仔细地编码它,都有机会加速,你没有预见到.这是我找到它们的方式. (有些人认为this method有争议).

最好在执行此操作时从优化标志OFF开始,因此代码不会全部加扰.
稍后你可以打开它们,让编译器做它的事情.

让它在具有足够工作负载的调试器下运行,以便运行一段合理的时间.
在它运行时,手动打断它,并仔细查看它正在做什么以及为什么.
这样做几次,比如10次,所以你不会对它花费的时间得出错误的结论.

以下是您可能会发现的事例:

>由于某些表达式的编码方式或与先前调用中相同的参数值,可能会花费大量时间不必要地调用数学库函数.
>它可能花费大量时间来执行某些文件I / O,或打开/关闭文件,深入到一些似乎无害的调用例程中.
>它可以在通用库函数中,调用从属子例程,以便检查上层函数的参数标志.在这种情况下,大部分时间可以通过编写一个专用函数并调用它来消除.

如果你做了两三次这样的整个操作,你就会删除那些在第一次写入时进入任何软件的愚蠢的东西.在那之后,你可以打开优化,并行性等等,并且相信没有时间花在愚蠢的事情上.

相关文章
相关标签/搜索