有限要素計算に使用してきた Fortran 90 コードがいくつかあります。最近、ブロック線形システムを解く方法を改善しようとしています。以前は、amux
疎な行列とベクトルの乗算に使用されるサブルーチンと、 を使用cg
して共役勾配法を実装する別のサブルーチンがありましたamux
。新しい行列ベクトル サブルーチンblock_amux
と、同様に新しいソルバーを作成しblock_cg
ました。当然のことながら、新しいメソッドはより高速に実行されるはずですが、代わりに実行速度が 10 倍遅くなります。
問題を追跡するために、プロファイラー gprof を使用して何が起こっているかを確認しました。コードの 92.5% がcg
サブルーチンの実行に費やされていることがわかりました。サブルーチンを呼び出したことがなく、block_amux と block_cg だけに依存していたにもかかわらずです。さらに混乱させるために、実際のcg
ルーチンに「Hello world」という print ステートメントを入れました。それは決して印刷されませんでした。最後に、gprof にはサブルーチンの使用法がリストされていないことに気付きましたamux
。ただし、cg を実際に呼び出すと、通常の行列の乗算が何百回も実行されます。
何がこれをしている可能性があるのか 、私は当惑しています。何かご意見は?それが役立つ場合は、gprof 出力を添付できます。
更新: 次の変更を加えましたが、何らかの方法で同じ結果が得られました。
- サブルーチンの名前を変更します。たとえば、becks
cg
ですconjugate_gradient
。次に、Gprof は、新しいconjugate_gradient ルーチンで時間を無駄にしていると報告します。 - 私が実際に使用するサブルーチンを
linalg_mod
、元々存在していたモジュールの代わりに「contains」ステートメントの下のメイン プログラムに移動し、CG ルーチンを含むモジュールの使用を停止します。代わりに、プログラムは「frame_dummy」と呼ばれるもので時間を浪費します。これは疑わしいほどこの投稿に似ているように見えますが、できません - 使用するサブルーチンを
linalg_mod
、CG ルーチンを含む から、それを含まlinalg_mod_decoy
ない新しいモジュール に移動します。CG アルゴリズムで時間を無駄にする代わりに、gprof は、プログラムが線形システムの右辺を生成するために使用するサブルーチンを 1 回だけではなく約 3000 回呼び出していることを示しています。 - 別のコンピューターで試してください。変わりはない。