2

我有一些用于有限元计算的 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 输出。

更新:我进行了以下更改,结果以某种方式或其他方式相同:

  1. 更改子例程的名称,例如cg变为conjugate_gradient. Gprof 然后报告说我在新的 conjugate_gradient 例程中浪费时间。
  2. 将我实际使用的子例程移动到“包含”语句下的主程序中,而不是linalg_mod它们最初所在的模块,然后停止使用包含 CG 例程的模块。相反,该程序将时间浪费在称为“frame_dummy”的东西上。这看起来与这篇文章非常相似,但我不能
  3. 将我使用的子例程从linalg_mod包含 CG 例程的 移动到linalg_mod_decoy不包含它的新模块。gprof 没有在 CG 算法中浪费时间,而是说该程序正在调用一个子程序,我用它来生成线性系统的右侧约 3000 次而不是一次。
  4. 在另一台计算机上尝试。没有不同。
4

1 回答 1

1

引用问题作者korrok 的评论:

OpenMP 是罪魁祸首。我想如果我将线程数设置为 1,我将得到与完全没有 OMP 的分析相同的结果。当我停止使用 OpenMP 进行编译时,它的性能仍然很差,但正确地报告了所有工作的完成位置。

于 2019-07-20T02:43:09.610 回答