Fortran中的纯子程序 - 编译器优化

Tib*_*ibo 14 fortran

我最近发现在Fortran中使用纯函数和子例程.从Fortran手册中可以看出,似乎我的大部分子程序实际上都可以定义为纯(因为我总是指定所有参数的意图,通常我没有"保存","暂停"或外部I/O在我的大部分子程序中).我的问题是:我应该这样做吗?我想知道编译器是否优化了更好的纯子程序,或者它是否无关紧要,或者它是否会使事情变得更糟.谢谢 !

Jon*_*rsi 20

您使用编译器生成良好的代码,并且您为编译器提供的信息越多,您们两个人可以一起完成的工作就越好.

无论是使用intent(in)任何伪参数进行标记,您都不会更改,或者使用parameter常量,或明确地制作pure任何没有任何副作用的子程序,或者forall在您不关心计算循环的顺序时使用,通过更明确地了解您想要发生的事情,您将受益,因为:

  • 编译器现在可以在编译时标记更多错误 - 嘿,你修改了你说的意图'in'的那个参数,或者你在纯子例程中修改了那个模块变量
  • 你的代码对下一个人来说更清楚,而不知道它应该做什么(那个人很可能是你三个月后)
  • 编译器可以更积极地进行优化(如果编译器保证您不会发生任何变化,它可以进行优化).

在这三个好处中,优化可能不是最重要的; 在纯子程序的情况下,智能编译器可能只能通过静态分析看到您的子程序没有副作用.尽管如此,您可以提供的保证越多,在保持正确性的同时优化代码的工作就越好.

  • 您可以使用“pure”关键字作为副作用检测器。只需将您编写的所有函数声明为“pure”即可。如果函数有副作用,编译器会抱怨。如果发生这种情况,请考虑是否可以将其重构为无副作用,否则删除“pure”。这样您将更好地理解您的代码并自动编写更清晰的代码。 (2认同)

Fra*_*acq 5

据我所知,它在顺序模式下无关紧要.但是,如果激活"自动并行化"选项,则编译器有时可以利用PURE声明来并行化包含对纯子例程的调用的循环(多线程)(如果子例程不纯,则不会冒风险).出于同样的原因,PURE声明对于想要手动设置//指令(例如OpenMP)的程序员也很有用,因为此类过程出现问题的风险相当有限.通常可以通过调用非纯子程序来并行化循环,但这需要深度验证......

  • 但另一方面,编译器可能不会并行化纯子例程中的任何内容,所以要小心. (3认同)