私は最近、並列コンピューティングとプログラミングについて多くのことを書いてきましたが、並列コンピューティングに関しては多くのパターンが出てくることに気付きました。Microsoft は、Microsoft Visual C++ 2010 コミュニティ テクニカル プレビュー (Parallel Patterns Library という名前) と共にライブラリを既にリリースしていることに注意してください。C++ で並列プログラムを作成する際に、従うイディオムやパターンはありますか?
4 に答える
パターン:
生産者/消費者
- 1 つのスレッドがデータを生成する
- 1 つのスレッドがデータを消費する
ループ並列処理
- 各ループが独立していることを示すことができれば、
各反復を別々のスレッドで実行できます
- 各ループが独立していることを示すことができれば、
再描画スレッド
- 他のスレッドは動作してデータ構造を更新しますが、1 つのスレッドが画面を再描画します。
メインイベント スレッド
- 複数のスレッドがイベントを生成できます
- 1 つのスレッドがイベントを処理する必要があります (順序が重要であるため)
- Event Thread/Re-Draw Thread を分離してみる必要があります。
これにより、UI がフリーズするのを防ぐことができますが、
慎重に行わないと過度の再描画が発生する可能性があります。
ワークグループ
- 一連のスレッドがキューでジョブを待機します。
- スレッドは、キューから 1 つの作業項目を抽出します (何も利用できない場合は待機します)。
スレッドは完了するまで 1 つの作業項目で動作
します。完了すると、スレッドはキューに戻ります。
並列実行パターン
決定論的パターンを使用した構造化並列プログラミングは、主に反復並列実行パターンのコレクションに基づく高レベルのアプローチであり、アルゴリズムスケルトンまたは並列構造と呼ばれることが多く、プログラムの説明を抽象化し、低レベルのマルチスレッドの詳細と並列処理に固有の多くの複雑さを隠します。プログラマーから。
これらの再利用可能なパターンは、同期、通信、データパーティショニング、タスクスケジューリングなど、多くの並列パラダイム関連ルーチンを自動化し、それらを内部で処理します。この高レベルのアプローチは、従来の低レベルのスレッドロックモデルを試み、より抽象化され、並列処理を表現し、パフォーマンスよりも生産性とプログラム可能性に焦点を当てる簡単な方法を備えています。
Map-Reduce、Fork-Join、Pipeline、Parallel Loopなど、一般的に使用されるパターンは多数あります。
論文
「決定論的パターンを用いた構造化並列プログラミング」は、これらのパターンについて論じた論文です。XPUという名前のこのアプローチのC++実装について説明している「MHPM:マルチスケールハイブリッドプログラミングモデル:柔軟な並列化方法論」もご覧ください。
としょうかん
XPUは、再利用可能な実行パターンのセットで構成されるタスクベースのC++ライブラリです。これにより、単一の同種プログラミングモデル内で、いくつかのレベルの粒度でいくつかのタイプの並列処理を表現できます。使い方は簡単で、パターンを使用して並列プログラムを設計することの目的を示しています。
たとえば、次の式を使用できます。
タスクの並列処理パターン:
共有データの自動検出や保護などのいくつかの機能を備えた、単純または階層的なフォーク/結合の実行パターン。
データ並列処理パターン:
スケーラブルなデータパーティショニングを備えた並列ループパターン。
時間的並列処理パターン:
パイプライン実行パターン。
まず、共有メモリ コンピューティングとシェアード ナッシング コンピューティングのどちらかを選択する必要があります。共有メモリの方が簡単ですが、それほどスケーリングしません。
a) マルチプロセッサ システムではなく、クラスタを使用する、または
b) 多くの CPU (たとえば、> 60) があり、高度に不均一なメモリがある場合
共有メモリの場合、一般的な解決策はスレッドを使用することです。概念として理解しやすく、API での使用も簡単です (ただし、デバッグは困難です)。
何も共有しない場合は、ある種のメッセージングを使用します。ハイ パフォーマンス コンピューティングでは、メッセージング ミドルウェアとして MPI が確立されています。
次に、並行アクティビティのアーキテクチャも設計する必要があります。最も一般的なアプローチ (これもわかりやすいため) は、農夫 - 労働者 - パターン (別名、マスター - スレーブ) です。