fortran错误地调用了一个子例程
我有一些Fortran 90代码,我一直在使用这些代码进行有限元计算。最近,我一直在努力改进它解决块线性系统的方法。之前,我有一个子例程fortran错误地调用了一个子例程,fortran,profiling,linear-algebra,fortran90,Fortran,Profiling,Linear Algebra,Fortran90,我有一些Fortran 90代码,我一直在使用这些代码进行有限元计算。最近,我一直在努力改进它解决块线性系统的方法。之前,我有一个子例程amux用于稀疏矩阵向量乘法,另一个子例程cg使用amux实现共轭梯度法。我编写了一个新的矩阵向量子程序block\u amux,同样,我还编写了一个新的解算器block\u cg。当然,新方法应该运行得更快,但它的运行速度却慢了10倍 为了追踪问题,我使用了探查器gprof来查看发生了什么。我发现92.5%的代码用于运行cg子例程——尽管我从未调用过它,并且完
amux
用于稀疏矩阵向量乘法,另一个子例程cg
使用amux
实现共轭梯度法。我编写了一个新的矩阵向量子程序block\u amux
,同样,我还编写了一个新的解算器block\u cg
。当然,新方法应该运行得更快,但它的运行速度却慢了10倍
为了追踪问题,我使用了探查器gprof来查看发生了什么。我发现92.5%的代码用于运行cg
子例程——尽管我从未调用过它,并且完全依赖于block\u amux和block\u cg。为了使水更加浑浊,我在实际的cg
例行程序中加入了一个打印语句,说“你好,世界”;它从未被印刷过。最后,我注意到gprof没有列出amux子例程的用法,即使对cg的真正调用会执行数百次普通矩阵乘法
我很困惑到底是什么在做这件事。有什么想法吗?如果有帮助的话,我可以附加gprof输出
更新:我做了以下更改,以某种方式产生了相同的结果:
cg
变为conjugate\u gradient
。然后Gprof报告说我在新的共轭梯度例程中浪费时间linalg_mod
,然后停止使用包含CG例程的模块。相反,该程序将时间浪费在所谓的“frame_dummy”中。这看起来很像,但我不能linalg\u mod
移动到不包含CG例程的新模块linalg\u mod\u decoy
。gprof没有在CG算法中浪费时间,而是说该程序调用了一个子程序,我用它来生成线性系统的右侧~3000次,而不是一次如果将“cg”子例程重命名为“dontcallthissubroutine”或其他名称,会发生什么情况?在这种情况下,我倾向于发现makefile中存在问题,并且我没有编译和运行我认为是的东西。这种想法发生在我身上。我把它重命名为“共轭梯度”,去掉了所有可执行文件、对象和模块文件,然后用同样的结果重建了所有文件。gprof报告说,在这个奇怪的子例程上花费了相同的时间,当然名称也改变了。不过,我将试着玩转如何编译所有内容。您可能已经知道这一点,但在重新编译之前,请确保清除旧的对象文件和创建的所有库。您的可执行文件的慢速版本是否有可能卡在缓存中?您是否尝试过从新的终端会话运行?或on/off开关?您使用哪种编译器?哪些优化标志有效?您的问题听起来很像内联和/或过程间优化之后发生的情况。每当编译插入指令的二进制文件时,应禁用内联和IPO。