7

重いシンボリック計算 (多くの複数のシンボリック積分) を含むコードがあります。また、8 コア CPU コンピューター (18 GB RAM) と小さな 32 CPU クラスターの両方にアクセスできます。限られた時間内にクラスターを使用して別の教授の研究室に行くよりも、教授の 8 コア PC にとどまることを好みますが、SMP システムで動作するかどうかわからないため、並行するものを探していますSMPクラスターの両方で使用できるPythonのツールであり、もちろん、あるシステムのコードを他のシステムで使用するために簡単かつ最小限の労力で変更できることを好みます。

これまでのところ、Parallel Python (PP) が私のニーズに有望であることがわかりましたが、最近、MPI も同じことを行うと言いました (pyMPI または MPI4py)。Web 上ではこれについてほとんど議論されていないように見えるため、これを承認できませんでした。ここでのみ、MPI (pyMPI または MPI4py の両方) がクラスターでのみ使用可能であると述べられています。

「Parallel Python」が私の唯一の選択肢ですか、それとも MPI ベースのソリューションを喜んで使用できますか? 私のニーズにとってどちらがより有望ですか?

PS。それらのどれも非常に包括的なドキュメントを持っていないようですので、並列計算の初心者を助けることができる公式Webサイト以外へのリンクを知っていれば、回答でそれらについても言及していただければ幸いです:)


編集します。

私のコードには 2 つのループがあり、外側のループは、前のステップで計算された値に応じて各ステップが反復メソッド (再帰的なソリューション)であるため、並列化できません。外側のループには内側のループと、内側のループの結果全体に依存する3 つの追加の方程式が含まれています。ただし、内側のループ(各ステップで計算可能な 12 個の方程式のうち 9 個を含む) は安全に並列化できます。すべての 3*3 方程式は互いに独立しており、前のステップにのみ依存します。私の方程式はすべて、それぞれが多くの複数のシンボリック積分を含んでいるため、計算量が非常に多くなります。一見、内側のループの 9 つの方程式を両方とも並列化できます。これらの 9 つの方程式のそれぞれの積分計算を個別に行い、内側のループと一緒に他の 3 つの方程式のすべての積分を並列化します。私の必要性をよりよく理解するのに役立つ場合は、ここで私のコードを見つけることができます。それはSageMath内に書かれています。

4

3 に答える 3

1

これを設計するには、いくつかの合理的な方法があるようです。

あなたの仕事を、メインの仕事、9 つの中間の仕事、および中間の仕事から派生できる多くの内部の仕事と呼びましょう。内部ジョブがすべて終了した後、中間ジョブには「マージ」ステップがあり、外部ジョブについても同じであると想定しています。

最も単純な設計は、メイン ジョブが中間ジョブを起動し、それらがすべて終了するのを待ってからマージ ステップを実行するというものです。次に、中間ジョブが内部ジョブを起動し、それらがすべて完了するのを待ってからマージ手順を実行します。

これは単一の共有キューで機能しますが、待機中にワーカープールをブロックしないキューが必要であり、すぐに使用できるとは思いませmultiprocessingん。すべてのプロセスが子に参加するのを待っているとすぐに、何も行われません。PoolQueue

これを回避する 1 つの方法は、継続渡しスタイルに変更することです。中間ジョブのどれが最後に終了するかがわかっている場合は、ハンドルを他の中間ジョブに渡し、外側のジョブの代わりに結合してマージを実行させることができます。そして、中間は同様にマージを最後の内部ジョブに渡します。

問題は、スケジューリングの問題がなくても、通常、最後に何が終了するかを知る方法がないことです。つまり、何らかの形式の共有 (セマフォなど) か、ジョブ間でネゴシエートするためにジョブ間でメッセージを渡す必要があるということです。上でそれを行うことができますmultiprocessing。唯一の問題は、それがジョブの独立性を破壊することであり、同時に共有された並行性のすべての面倒な問題に突然対処することになります。

別の方法として、中間ジョブごとに個別のプールとキューを用意し、プール間である種の負荷分散を行うことで、各コアが 1 つのアクティブなプロセスを実行していることを確認できます。

multiprocessingまたは、もちろん、ロード バランシングまたは協調スケジューリングのいずれかを行う 'sよりも複雑な実装を持つ単一のプールであるため、ジョイナーはコアをブロックしません。

または、非常に単純な解決策: スケジュールをオーバースケジュールし、単純化するためにコンテキストの切り替えに多少のコストを支払います。たとえば、コアが 8 つしかなくても 32 個のワーカーを実行できるため、22 個のアクティブなワーカーと 10 個の待機中のワーカーがあります。各コアには 2 つまたは 3 つのアクティブなワーカーがあり、少し遅くなりますが、それほど悪くはありません。また、少なくとも誰もアイドル状態ではなく、別のパラメーターをmultiprocessing.Poolコンストラクターに渡す以外にコードを記述する必要はありませんでした。

いずれにせよ、multiprocessing非常にシンプルで、他のソリューションに当てはまらない余分な概念はほとんどありません。したがって、レンガの壁にぶつかるまで、またはぶつからないまで、それがうまくいくかどうかを事前に把握しようとするよりも、それをいじるのにかかる時間は短いかもしれません.

于 2012-11-29T21:41:47.990 に答える
-1

私は最近、同様の問題に遭遇しました。ただし、次の解決策は、(1)ファイルのグループに対してPythonスクリプトを個別に実行する場合、および(2)スクリプトの各呼び出しが他の呼び出しから独立している場合にのみ有効です。

上記が当てはまる場合、最も簡単な解決策は、次の行に沿ってbashでラッパーを作成することです。

for a_file in $list_of_files
do
    python python_script.py a_file &
done

'&'は、前のコマンドをサブプロセスとして実行します。利点は、bashがforループを続行する前にPythonスクリプトが終了するのを待たないことです。

このコードは使用可能なすべてのリソースを使用するため、同時に実行されるプロセスの数に上限を設けることをお勧めします。

于 2012-11-29T01:23:19.630 に答える