我有一些用于有限元计算的 Fortran 90 代码。最近,我一直在尝试改进它解决块线性系统的方式。之前,我有一个amux
用于稀疏矩阵向量乘法的子程序和另一个cg
使用amux
. 我写了一个新的矩阵向量子程序block_amux
和一个新的求解器block_cg
。无论如何,新方法应该运行得更快,但它的运行速度却慢了 10 倍。
为了追查问题,我使用分析器 gprof 来查看发生了什么。我发现我 92.5% 的代码都花在了运行cg
子程序上——尽管我从未调用过它,并且完全依赖于 block_amux 和 block_cg。为了进一步搅浑水,我在实际的cg
例程中添加了一个打印语句,说“Hello world”;它从未被打印出来。最后,我注意到 gprof 没有列出amux
子例程的用途,即使真正调用 cg 会完成数百次普通的矩阵乘法。
我对这可能是什么感到困惑。有什么想法吗?如果这也有帮助,我可以附加 gprof 输出。
更新:我进行了以下更改,结果以某种方式或其他方式相同:
- 更改子例程的名称,例如
cg
变为conjugate_gradient
. Gprof 然后报告说我在新的 conjugate_gradient 例程中浪费时间。 - 将我实际使用的子例程移动到“包含”语句下的主程序中,而不是
linalg_mod
它们最初所在的模块,然后停止使用包含 CG 例程的模块。相反,该程序将时间浪费在称为“frame_dummy”的东西上。这看起来与这篇文章非常相似,但我不能 - 将我使用的子例程从
linalg_mod
包含 CG 例程的 移动到linalg_mod_decoy
不包含它的新模块。gprof 没有在 CG 算法中浪费时间,而是说该程序正在调用一个子程序,我用它来生成线性系统的右侧约 3000 次而不是一次。 - 在另一台计算机上尝试。没有不同。