我有一些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”的东西。这看起来与this post非常相似,但我不能linalg_mod
移动到新模块linalg_mod_decoy
,该模块不包含它。 gprof不是在CG算法中浪费时间,而是说程序正在调用一个子程序,用于生成线性系统的右侧〜3000次而不是一次。答案 0 :(得分:0)
引用a comment by korrok,问题作者:
OpenMP是罪魁祸首。我发现,如果将线程数设置为1,我将得到与完全没有OMP的分析结果相同的结果。当我停止使用OpenMP进行编译时,它的性能仍然很差,但是正确报告了所有工作的完成位置。