4

計算力学の研究のために、c++ を使用していくつかのコードを開発しています。私のコードは、疎行列と密行列を解き、メッシュを生成し、最も些細な意味で同様の操作を行います。計算時間を短縮するためにコードを並列化する必要があり、そのために OpenMP を使用しました。

しかし、ANSYS CFX などの市販のコードを詳しく調べたところ、そのソフトウェアで使用されている並列化スキームは、MPI の実装である MPICH2 であることがわかりました。

したがって、多くの並列化ツール/API があります。

  • OpenMP
  • MPI
  • インテル スレッディング ビルディング ブロック
  • Pスレッド
  • マイクロソフト PPL

これらのツールのいくつかを使用し、それぞれを使用してローカル コンピューターの CPU 使用率を 100% にすることができました。

適切な並列化ツールを選択する際に注意すべき基準がわかりません。どの種類のアプリケーションがどのツールを必要としますか? 上記のいずれかが研究目的で使用できますか? 商用ソフトウェアで主に使用されているのはどれですか?

4

2 に答える 2

7

このタイプの多くの質問には、真の決定的な答えはありません。答えは常に「場合による」ため、どちらが優れているとは言えません。何をしているのか、コードの書き方、移植性の要件などについて。

あなたのリストに従ってください:

  • OpenMP : かなり標準的で、本当に使いやすいことがわかりました。元のコードが並列化を念頭に置いて書かれていない場合でも、このライブラリにより段階的なアプローチが非常に簡単になります。すべてを簡単にするかもしれないが、デバッグが難しく、パフォーマンスが制限され、コードを並列にするだけなので、並列コンピューティングの良いエントリーポイントだと思います(並列アルゴリズム、構造、プリミティブが欠けており、作業を複数にまたがることができません)。ネットワーク)。
  • Message Passing Interface : 私の観点からは、この標準に基づくライブラリは、クラスター全体で大規模な計算を行うのに最適です。コンピューターがほとんどなく、計算を並行して行いたい場合、これはよく知られていて安定した良い選択です。これは (やはり私の見解では)ローカル並列化のソリューションではありません。広く使用されているグリッド コンピューティングの標準を探している場合は、MPI が最適です。
  • Intel Threading Building Blocks : これは、さまざまな環境 (pthread または Windows のスレッド モデル) 間でマルチスレッドのインターフェイスを統一するための C++ ライブラリです。このようなライブラリを使用する場合、コンパイラや環境間で移植可能である必要があるかもしれません。さらに、このライブラリを使用しても制限がないため、他のもの (MPI など) とうまく統合できます。ライブラリを見て、気に入るかどうかを確認してください。これは、優れた設計で、十分に文書化され、広く使用されている非常に良い選択です。
  • Microsoft Parallel Patterns Library : これは非常に大きなライブラリです。これは非常に新しいので、適切なテストなしで誰かに使用するように提案するのは安全ではありません。さらに、Microsoft 固有であるため、コンパイラに縛られています。それは、私が見ているものは素晴らしい図書館だと言いました。多くの詳細を抽象化し、適切に設計されており、「並列タスク」の概念の非常に高いレベルのビューを提供します。繰り返しになりますが、このライブラリを使用しても、たとえばクラスター用の MPI を使用する必要はありません (ただし、コンカレンシー ランタイムにはこのための独自のライブラリがあります)。

何を使う?私には答えがありません。より快適に感じるものを選んでみてください ( Boost Threadsも参照してください)。OpenMP+MPI、MPI+TBB、さらには MPI+PLL など、何らかの方法でそれらを混在させることができることに注意してください)。私の好みは PPL ですが、実際のアプリケーションを開発している場合は、どちらが優れているかを判断するために長いテストが必要になる場合があります。実際、私はコンカレンシー ランタイム (PPL のベース) が好きです。それは「水平」であり、並列計算のための基本的なフレームワーク (構造とアルゴリズムを含む) と多くの「垂直」パッケージ (エージェント、PPL、TPL ) を提供するからです。

つまり、計算を並列化した場合、CPU を集中的に使用するルーチンのパフォーマンスを改善する必要があるかもしれません。このタスクに GPU の使用を検討することもできますが、短時間の大規模な並列計算に最適だと思います(もちろん、CUDA のパフォーマンスが高くても、独自のCUDAよりもOpenCLを好みます)。実際、このトピックに興味がある場合は、 OpenHMPPを参照することもできます。

于 2012-06-05T18:13:39.173 に答える
3

これは、アドリアーノの回答に対する拡張コメント (および拡張) と考えてください。

OpenMP は、マスターして使用するのが非常に簡単で、シリアル実行可能ファイルと並列実行可能ファイルの両方を 1 つの同じソース コードから生成できるという優れた機能を備えています。既存のシリアル コードをパラレル コードに変換する必要がある場合は、段階的な並列化パスを使用することもできます。ただし、OpenMP には一連の欠点があります。まず、大規模な x86 SMP マシンが現在利用可能ですが、スケーラビリティを大幅に制限する共有メモリ マシンのみを対象としています (たとえば、クラスター インストールで最大 2 TiB の共有 RAM を共有する 128 CPU コアを備えた QPI 結合 Xeon システムを使用しています。大規模な OpenMP ジョブ)。第 2 に、そのプログラミング モデルは単純すぎて、いくつかの高度な概念を実装できません。しかし、OpenMP を簡潔に保つため、これはモデルの欠点ではなく長所であると言えます。

MPIはデファクトです現在では標準のメッセージ パッシング API です。広くサポートされており、多種多様な並列アーキテクチャで実行されます。その分散メモリ モデルは、基盤となるハードウェアにほとんどまたはまったく制限を課さず (低レイテンシと高帯域幅のネットワーク インターコネクトを備えていることを除けば)、数十万の CPU コアに拡張できます。MPI プログラムは、ソース レベルではかなり移植性がありますが、アルゴリズム自体は移植可能なスケーラビリティを備えていない場合があります (たとえば、1 つの MPI プログラムが Blue Gene/P で非常に効率的に実行され、InfiniBand クラスターでは非常に遅くなる場合があります)。MPI には重大な欠点が 1 つあります。その SPMD (Single Program Multiple Data) モデルは、プログラマーに代わって多くの統合失調症の思考を必要とし、OpenMP よりも習得がはるかに困難です。シリアル アルゴリズムを MPI に移植することは、OpenMP の場合ほど簡単ではなく、高い並列効率を達成するために完全な書き直しが必要になる場合があります。また、段階的な並列化アプローチを採用して、シリアル実行可能ファイルと並列実行可能ファイルの両方を生成できるコードベースを簡単に維持することもできません。MPI には興味深い機能があります。別のノードで実行されるプログラムのさまざまな部分を完全に分離し、ネットワークへの抽象的なインターフェイスを提供するため、異種コンピューティングが可能になります。いくつかの MPI 実装 (Open MPI など) は異種サポートを提供します。これにより、異なる OS で実行されているノードだけでなく、異なる「ビット数」とエンディアンを持つ CPU も混在させることができます。また、段階的な並列化アプローチを採用して、シリアル実行可能ファイルと並列実行可能ファイルの両方を生成できるコードベースを簡単に維持することもできません。MPI には興味深い機能があります。別のノードで実行されるプログラムのさまざまな部分を完全に分離し、ネットワークへの抽象的なインターフェイスを提供するため、異種コンピューティングが可能になります。いくつかの MPI 実装 (Open MPI など) は異種サポートを提供します。これにより、異なる OS で実行されているノードだけでなく、異なる「ビット数」とエンディアンを持つ CPU も混在させることができます。また、段階的な並列化アプローチを採用して、シリアル実行可能ファイルと並列実行可能ファイルの両方を生成できるコードベースを簡単に維持することもできません。MPI には興味深い機能があります。別のノードで実行されるプログラムのさまざまな部分を完全に分離し、ネットワークへの抽象的なインターフェイスを提供するため、異種コンピューティングが可能になります。いくつかの MPI 実装 (Open MPI など) は異種サポートを提供します。これにより、異なる OS で実行されているノードだけでなく、異なる「ビット数」とエンディアンを持つ CPU も混在させることができます。MPI には興味深い機能があります。別のノードで実行されるプログラムのさまざまな部分を完全に分離し、ネットワークへの抽象的なインターフェイスを提供するため、異種コンピューティングが可能になります。いくつかの MPI 実装 (Open MPI など) は異種サポートを提供します。これにより、異なる OS で実行されているノードだけでなく、異なる「ビット数」とエンディアンを持つ CPU も混在させることができます。MPI には興味深い機能があります。別のノードで実行されるプログラムのさまざまな部分を完全に分離し、ネットワークへの抽象的なインターフェイスを提供するため、異種コンピューティングが可能になります。いくつかの MPI 実装 (Open MPI など) は異種サポートを提供します。これにより、異なる OS で実行されているノードだけでなく、異なる「ビット数」とエンディアンを持つ CPU も混在させることができます。

Intel TBB は、強化された OpenMP のようなものです。CUDA や OpenCL などの他の並列プログラミング パラダイムに近づける、カーネルに基づくより豊富なプログラミング モデルを提供します。適用性と拡張性の点で、C++ STL アルゴリズムから多くを引き出します。また、コンパイラに中立であると想定されており、原則としてインテル C++ コンパイラ、GNU g++、および MSVC で動作するはずです。ITBB はまた、イデオロギーを「盗む」タスクを使用します。これは、予防策が講じられていない場合に以前のパラダイムで発生しがちだった計算上の不均衡を潜在的に均一化できる可能性があります。

Pthreads は、最新の Unix 系 (FreeBSD、Mac OS X、Linux など) の移植可能なスレッド化インターフェースです。これは単なるスレッド ライブラリであり、想像できる最も一般的な使用例を対象としています。並列構造はほとんどまたはまったく提供されず、その上にそれらを明示的にプログラムする必要があります。たとえば、OpenMP の単純なループ反復分散でさえ、手作業でコーディングする必要があります。Unix にとっての Pthreads は、Windows にとっての Win32 スレッドとまったく同じです。

(私はそのライブラリをよく知らないので、Microsoft TPP はスキップします)

単一ノードがますます多くのコアを獲得しているため、これらの概念を混合することは明らかに将来の道です。ほとんどのアルゴリズムで複数レベルの並列処理が可能であり、MPI を使用して粗粒度の並列処理 (複数のクラスター ノードで実行) を実行でき、OpenMP または ITBB を使用して個々のノード計算の細粒度分割を実行できます。共有メモリ プログラミングでは、メモリ リソースがすべてスレッド間で共有され、キャッシュの再利用などによって計算が大幅に高速化されるため、通常、メモリ リソースをより有効に活用できます。MPI はマルチコア SMP または NUMA マシンのプログラミングにも使用できますが、各 MPI プロセスは独自の仮想アドレス空間を持つ個別の OS プロセスであるため、多くの (構成) データを複製する必要がある場合があります。

プログラミングのバックグラウンドに最も近いものを選択することをお勧めします。あなたが熱心な C++ プログラマーであり、抽象化に慣れている場合は、Intel TBB (または .Net に興味がある場合は Microsoft PPL) を選択してください。OpenMP は習得が非常に簡単で、優れたパフォーマンスを提供しますが、どこか単純化されています。これは、Fortran でマルチスレッド コードを記述するための唯一の広く利用可能で使用されているメカニズムです。MPI の学習曲線は急ですが、プログラムが単一のコンピューティング ノードで提供できる範囲を超えた場合は、いつでも追加できます。

于 2012-06-05T21:25:19.290 に答える