我有一些Fortran 90代码,我一直在使用有限元计算。最近,我一直在尝试改进它解决块线性系统的方式。之前,我有一个用于稀疏矩阵向量乘法的子程序amux
和另一个使用amux
实现共轭梯度法的子程序cg
。我写了一个新的矩阵向量子程序block_amux
和一个新的求解器block_cg
。按理说,这种新方法应该运行得更快,但它的运行速度却慢了10倍。
为了追踪问题,我使用了分析器gprof来查看发生了什么。我发现92.5%的代码用于运行cg
子例程——尽管我从未调用过它,并且完全依赖于block_amux和block_cg。为了进一步混淆,我在实际的cg
例程中添加了一个print语句,说"Hello world";它从未被印刷出来。最后,我注意到gprof没有列出amux
子例程的使用,即使真正调用cg会执行数百次普通的矩阵乘法。
我很困惑是什么在做这件事。任何想法吗?如果有帮助的话,我可以附加gprof输出。
更新:我已经做了以下更改,以相同的方式或其他结果:
- 修改子程序的名称,例如将
cg
改为conjugate_gradient
。gprofthen报告说,我在新的共轭梯度例程中浪费时间。 - 将我实际使用的子例程移动到我的主程序下的"包含"语句,而不是它们最初驻留的模块
linalg_mod
,然后停止使用包含CG例程的模块。相反,程序将时间浪费在一个叫做"frame_dummy"的东西上。这看起来很像这篇文章,但我不能 - 将我使用的子例程从包含CG例程的
linalg_mod
移动到不包含CG例程的新模块linalg_mod_decoy
。为了避免在CG算法上浪费时间,gprof表示,该程序调用了我用来生成线性系统右侧的子程序~3000次,而不是一次。 在另一台计算机上试试。没有区别。
引用问题作者korrok的评论:
OpenMP是罪魁祸首。我认为,如果我将线程数设置为1,我将得到与没有OMP的分析相同的结果。当我停止用OpenMP编译时,它仍然表现不佳,但正确报告了所有工作正在完成的地方。