46

今日、新しいアプリケーションを最初から作成していて、明日スローできるすべてのコアに拡張したい場合、どの並列プログラミングモデル/システム/言語/ライブラリを選択しますか?なんで?

私はこれらの軸に沿った答えに特に興味があります:

  1. プログラマーの生産性/使いやすさ(人間はそれをうまく使うことができますか?)
  2. ターゲットアプリケーションドメイン(どのような問題が(得意ではない)得意ですか?)
  3. 同時実行スタイル(タスク、パイプライン、データ並列処理、メッセージをサポートしていますか...?)
  4. 保守性/将来性(20年後もまだ使用されている人はいますか?)
  5. パフォーマンス(どの種類のハードウェアでどのように拡張できますか?)

さまざまなアプリケーションに役立つ一般的な回答が得られることを期待して、アプリケーションの性質について意図的に曖昧にしています。

4

22 に答える 22

27

マルチコアプログラミングでは、実際には複数のパラダイムが必要になる場合があります。現在の候補者は次のとおりです。

  1. MapReduce。これは、問題を並列チャンクに簡単に分解できる場合にうまく機能します。
  2. ネストされたデータの並列処理。これはMapReduceに似ていますが、再帰的なチャンクのサイズが不規則な場合でも、実際には問題の再帰的な分解をサポートします。NDPが、超並列であるが制限されたハードウェア(GPUなど)で実行される純粋な関数型言語で大きな勝利となることを期待してください。
  3. ソフトウェアトランザクショナルメモリ。従来のスレッドが必要な場合、STMはそれらを耐えられるようにします。クリティカルセクションで50%のパフォーマンスヒットを支払いますが、複雑なロックスキームを数百のプロセッサに簡単に拡張できます。ただし、これは分散システムでは機能しません。
  4. メッセージングを使用した並列オブジェクトスレッド。この本当に賢いモデルはErlangによって使用されています。各「オブジェクト」は軽量スレッドになり、オブジェクトは非同期メッセージとパターンマッチングによって通信します。それは基本的に真の並列OOです。これは、いくつかの実際のアプリケーションでうまく成功しており、信頼性の低い分散システムに最適です。

これらのパラダイムのいくつかは最大のパフォーマンスを提供しますが、問題が完全に分解された場合にのみ機能します。他の人はパフォーマンスをいくらか犠牲にしますが、より多様なアルゴリズムを許可します。上記のいくつかの組み合わせが最終的に標準のツールキットになると思います。

于 2008-09-17T15:10:10.417 に答える
14

私が本当に気に入っている 2 つのソリューションは、結合計算( JoCamlPolyphonic C# ) とアクター モデル( ErlangScalaEIo ) です。

Software Transactional Memoryには特に感銘を受けません。何十年も前に死ぬべきだったのに、スレッドがもう少し長く生き続けることができるようにするためだけにあるように感じます. ただし、次の 3 つの大きな利点があります。

  1. 人々はデータベース内のトランザクションを理解しています
  2. トランザクション RAM ハードウェアの話はすでにあります
  3. 悲しいことに、スレッドがなくなることを誰もが望んでいますが、今後数十年間はおそらくスレッドが主要な同時実行モデルになるでしょう。STMは痛みを大幅に軽減する可能性があります。
于 2008-09-17T05:04:04.133 に答える
11

mapreduce / hadoopパラダイムは有用であり、関連性があります。特にperlのような言語に慣れている人にとっては、配列をマッピングして各要素に対して何らかのアクションを実行するというアイデアは、かなり流動的かつ自然に実現するはずです。mapreduce/ hadoopはそれを次の段階に進め、理由はないと言います。配列の各要素は同じマシンで処理する必要があります。

Googleはmapreduceを使用しており、多くの人がhadoopを使用しており、ネットワーク上の複数のマシンにまたがるアプリケーションのスケーリングに適していることを示しているため、ある意味では、より多くのバトルテストが行​​われています。また、ネットワーク全体で複数のマシンに拡張できる場合は、1台のマシンで複数のコアに拡張できます。

于 2008-09-17T04:35:18.667 に答える
10

.NETアプリケーションの場合、「。NET Parallel Extensions(PLINQ)」を選択します。これは非常に使いやすく、既存のコードを数分で並列化できます。

  1. 学ぶのは簡単です
  2. オブジェクトの大きな配列に対して複雑な操作を実行するために使用されるため、他のアプリケーションについてコメントすることはできません
  3. タスクとパイプラインをサポートします
  4. 今後数年間はサポートする必要がありますが、誰が確実に知っていますか?
  5. CTPバージョンにはいくつかのパフォーマンスの問題がありますが、すでに非常に有望に見えます。

MonoはPLINQをサポートする可能性が高いため、クロスプラットフォームソリューションになる可能性もあります。

于 2008-09-17T04:33:07.220 に答える
6

重い計算などの場合、 Haskellのような純粋な関数型言語は、プログラマー側の努力なしで簡単に並列化できます。Haskell の学習は別として、つまり。

しかし、これが(近い)将来のやり方だとは思いません。単純に、あまりにも多くのプログラマーが命令型プログラミング パラダイムに慣れすぎているからです。

于 2008-09-17T04:46:01.103 に答える
5

kamaeliaは、多くの通信プロセスを備えたアプリケーションを構築するためのPythonフレームワークです。

Kamaelia-並行性が便利で楽しいものになりました

Kamaeliaでは、相互に通信する単純なコンポーネントからシステムを構築します。これにより、開発がスピードアップし、メンテナンスが大幅に支援され、自然に並行ソフトウェアを構築できるようになります。これは、初心者を含むすべての開発者がアクセスできるようにすることを目的としています。それはまたそれを楽しくします:)

どんなシステム?ネットワークサーバー、クライアント、デスクトップアプリケーション、pygameベースのゲーム、トランスコードシステムとパイプライン、デジタルTVシステム、スパム根絶者、教育ツール、その他かなりの量:)

マルチコアと並行性に関する質問-言語、ライブラリ、開発手法も参照してください。

于 2008-09-18T01:20:15.630 に答える
4

TwistedEAmbientTalkなどのシステムで実現されているように、私はイベントループをpromiseと通信することに賭けています。それらは、非並行/並列アプリケーションと同じ実行モデルの仮定でコードを書く能力を保持しますが、分散および並列システムにスケーリングします。(それが私がエクリュに取り組んでいる理由です。)

于 2008-09-17T04:36:19.957 に答える
2

Erlangをチェックしてください。Google で検索して、さまざまなプレゼンテーションやビデオをご覧ください。私が尊敬するプログラマーやアーキテクトの多くは、そのスケーラビリティーにすっかり魅了されています。かなり重労働な場所で使用しています...

于 2008-09-17T04:40:56.483 に答える
2

前述のように、純粋関数型言語は本質的に並列化可能です。しかし、命令型言語は多くの人にとってはるかに直感的であり、私たちは命令型のレガシー コードに深く関わっています。基本的な問題は、純粋関数型言語は副作用を明示的に表現するのに対し、命令型言語ではステートメントの順序によって副作用が暗黙的に表現されることです。

副作用を宣言的に表現する手法 (たとえば、オブジェクト指向フレームワーク) により、コンパイラは命令文を機能的な関係に分解できるようになると私は信じています。これにより、純粋な機能コードとほぼ同じ方法で、コードを自動的に並列化できるようになります。

もちろん、パフォーマンスが重要な特定のコードをアセンブリ言語で記述することが依然として望ましいのと同様に、明日もパフォーマンスが重要な明示的な並列コードを記述する必要があります。ただし、私が概説したような手法は、開発者が最小限の労力でメニーコア アーキテクチャを自動的に活用するのに役立つはずです。

于 2008-09-17T15:32:58.710 に答える
2

この質問は、さまざまな表現で表示され続けているようです。StackOverflow 内にさまざまな構成要素がある可能性があります。 フローベースのプログラミング(FBP) は、30 年以上にわたって存在する概念/方法論であり、カナダの大手銀行でほとんどのバッチ処理を処理するために使用されています。Java と C# にはスレッドベースの実装がありますが、以前の実装はファイバーベース (C++ とメインフレーム アセンブラー - 銀行で使用されていたもの) でした。マルチコアを利用するという問題へのアプローチのほとんどは、従来のシングル スレッド プログラムを使用して、どの部分を並行して実行できるかを判断することを含みます。FBP は異なるアプローチを採用しています。アプリケーションは、非同期で実行される複数の「ブラックボックス」コンポーネント (製造組立ラインを考えてください) という観点から最初から設計されています。コンポーネント間のインターフェイスはデータ ストリームであるため、FBP は基本的に言語に依存せず、混合言語のアプリケーションをサポートします。ドメイン固有の言語。同じ理由で、副作用が最小限に抑えられます。これは、「何も共有しない」モデルであり、MOM (メッセージ指向ミドルウェア) とも言えます。MapReduce は FBP の特殊なケースのようです。FBP と Erlang の主な違いは、Erlang は多数の存続期間の短いスレッドで動作することです。そのため、そこではグリーン スレッドがより適切であるのに対し、FBP はより少数 (通常は数十から数百) の存続期間のスレッドを使用します。のために 一方、FBP はより少ない (通常は数十から数百) 存続期間の長いスレッドを使用します。のために 一方、FBP はより少ない (通常は数十から数百) 存続期間の長いスレッドを使用します。のために30 年以上にわたって日常的に使用されているバッチ ネットワークの一部です。バッチ ネットワークの一部を参照しください。対話型アプリの高レベルの設計については、仲介アプリの高レベルの設計を参照してください。FBP を使用すると、アプリケーションの保守性が大幅に向上し、経過時間が改善されることがわかっています。シングル コア マシンでも同様です。

于 2009-06-02T15:55:15.020 に答える
1

複数のワーカーシステムを備えたジョブキュー(正しい用語がわからない-メッセージキュー?)

なんで?

主に、それはとてつもなく単純な概念だからです。処理が必要なもののリストがあり、次にジョブを取得して処理する一連のプロセスがあります。

また、理由とは異なり、たとえば、HaskellまたはErlangは非常に同時/並列化可能(?)ですが、完全に言語に依存しません-そのようなシステムをC、Python、または他の言語(シェルスクリプトを使用している場合でも)で簡単に実装できます、一方、bashがソフトウェアトランザクショナルメモリまたはjoin-calculusをすぐに取得することはないと思います。

于 2009-06-02T16:48:07.447 に答える
1

Qtコンカレントは、非常に使いやすいマルチコア用のMapReduceの実装を提供します。multiOSです。

于 2008-09-17T04:34:36.763 に答える
1

今日、新しいアプリケーションを最初から作成していて、明日スローできるすべてのコアに拡張したい場合、どの並列プログラミングモデル/システム/言語/ライブラリを選択しますか?

おそらく、今日最も広く適用できるのは、Cilkスタイルのタスクキュー(現在は.NET 4で利用可能)です。これらは、分割統治法を使用してサブタスクの予測可能な複雑さで解決できる問題(関数の引数の複雑さがわかっている並列配列mapreduceオーバーアレイ、クイックソートなどのアルゴリズムなど)に最適であり、多くの実際の問題をカバーします。

さらに、これは今日のマルチコアのような共有メモリアーキテクチャにのみ適用されます。この基本的なアーキテクチャがすぐになくなるとは思いませんが、ある時点で分散並列処理と組み合わせる必要があると思います。これは、マルチコア間でメッセージが渡されるメニーコアCPU上のマルチコアのクラスターの形式か、コア間の通信時間が予測可能なコアの階層の形式になります。これらは、最大の効率を得るために実質的に異なるプログラミングモデルを必要とし、私はそれらについてあまり知られていないと思います。

于 2010-05-23T19:23:46.870 に答える
1

並列プログラミング IMO には、並列処理の識別と並列処理の指定という 3 つの部分があります。識別=アルゴリズムを並行作業のチャンクに分割し、指定=実際のコーディング/デバッグを実行します。識別は、並列処理を指定するために使用するフレームワークとは無関係であり、フレームワークがそれほど役立つとは思いません。アプリ、ターゲット プラットフォーム、一般的な並列プログラミングのトレードオフ (ハードウェア レイテンシなど) を十分に理解し、最も重要な経験が必要です。ただし、指定することは議論できます。これが私が以下で答えようとしているものです:

私は(学校や職場で)多くのフレームワークを試しました。すべてが共有メモリであるマルチコアについて質問されたので、私が使用した 3 つの共有メモリ フレームワークに固執します。

Pthreads (実際にはフレームワークではありませんが、確実に適用可能です):

長所: -Pthreads は非常に一般的です。私にとって、pthreads は並列プログラミングの組み立てのようなものです。pthread では、任意のパラダイムをコーディングできます。-柔軟なので、必要に応じて高性能にすることができます。あなたを遅くする固有の制限はありません。独自のコンストラクトとプリミティブを記述して、可能な限り高速化できます。

短所: -作業キューの管理、タスクの分散など、すべての配管を自分で行う必要があります。-実際の構文は見苦しく、多くの場合、アプリには多くの余分なコードが含まれているため、コードを書きにくく、読みにくくなっています。

OpenMP:

長所: -コードはきれいに見え、配管とタスク分割はほとんど内部で行われます -セミフレキシブル。仕事のスケジューリングのためのいくつかの興味深いオプションを提供します

短所: -並列処理のような単純な for ループを意味します。(新しい Intel バージョンもタスクをサポートしていますが、タスクは Cilk と同じです)。-基礎となる構造は、パフォーマンスのために適切に作成されている場合とそうでない場合があります。GNU の実装は問題ありません。Intel の ICC の方がうまく機能しましたが、より高いパフォーマンスを得るには、自分で何かを書きたいと思います。

Cilk、インテル TBB、Apple GCD:

長所: -タスクレベルの並列処理に最適な基本アルゴリズムであることが証明されている -シリアル/並列タスクの適切な制御 -TBB には、私が使用したパイプライン並列処理フレームワークもあります (率直に言うと、最適ではありません) -大量の書き込みタスクが不要になりますタスクベースのシステム用のコードの数。

短所: -基礎となる構造のパフォーマンスを制御しにくい。Intel TBB の基盤となるデータ構造のパフォーマンスが非常に低いことは知っています。たとえば、ワーク キューが不良でした (2008 年に見たとき)。-コードは、彼らがあなたに使ってほしいキーワードやバズワードをすべて含んでいるため、時々ひどいものに見えます -彼らの「柔軟な」APIを理解するには、多くの参考文献を読む必要があります

于 2011-05-10T00:27:31.000 に答える
1

問題のドメインが許す場合は、共有なしモデルについて考えてみてください。プロセスとスレッド間での共有が少なければ少ないほど、複雑な並行性モデルを設計する必要が少なくなります。

于 2008-09-17T04:59:33.350 に答える
1

価値のあるパスはOpenCLかもしれません。これは、特定の種類の計算負荷を異種の計算リソースに分散する手段を提供します。つまり、同じコードがマルチコア CPU とコモディティ GPU で実行されます。ATI は最近、まさにそのようなツールチェーンをリリースしました。NVidia のCUDAツールチェーンも同様ですが、多少制限があります。また、Nvidia は OpenCL SDKを開発中のようです。

ワークロードがデータ並列の性質のものではない場合、これはおそらくあまり役​​に立たないことに注意してください。たとえば、典型的なトランザクション処理ではあまり役に立ちません。OpenCL は主に、科学/工学シミュレーションや金融モデリングなど、数学を多用する種類のコンピューティングを対象としています。

于 2009-08-28T04:52:57.153 に答える
1

スケーラブルなプログラム分析および変換システム ( DMS Software Reengineering Toolkit) 数値計算ではなく記号計算を主に行います。PARLANSE は、従来のスカラー データ型の文字、整数、浮動小数点数、動的データ型の文字列と配列、複合データ型の構造体と共用体、およびレキシカル スコープの関数を備えた、コンパイルされた C に似た言語です。ほとんどの言語は基本的なもの (オペランドに対する算術式、if-then-else ステートメント、do ループ、関数呼び出し) ですが、並列処理はそうではありません。並列処理は、次のように記述されるコード ブロック (たとえば、b の前に a、c の前に a、c の前に d) の "先行する" 関係を定義することによって表現されます。

(|;  a  (... a's computation)
     (<< a) b ( ... b's computation ... )
     (<< a) c ( ....c's computation ...)
     (>> c) d ( ... d's computation...)
)|;

ここで、 << および >> 演算子は「時間順」を表します。PARLANSE コンパイラは、これらの並列計算を確認し、計算粒度 a、b、c、d に必要なすべての構造体を事前に割り当て、それぞれを開始/停止するカスタム コードを生成することで、これらの並列粒度を開始および停止するためのオーバーヘッドを最小限に抑えます。

8 パズルの 4x4 ビッグブラザーである15 パズルの最適解の並列反復深化検索については、このリンクを参照してください。これは、計算a b c dに半順序制約がないことを示す並列処理構造 (|| abcd )として潜在的な並列のみを使用しますが、投機も使用し、解が見つからないタスクを非同期的に中止します。かなり小さなコードに多くのアイデアが含まれています。

PARLANSE はマルチコア PC 上で動作します。大規模な PARLANSE プログラム (100 万以上の行を含む多くのプログラムを作成しました) には、これらの部分順序が何千もあり、そのうちのいくつかは他の部分を含む関数を呼び出します。これまでのところ、最大 8 個の CPU で良好な結果が得られており、最大 16 個の CPU で中程度の利益が得られています。また、システムの調整を続けています。(現在の PC で多数のコアを使用する場合の実際の問題は、メモリ帯域幅であると考えています。16 コアでメモリ サブシステムを処理すると、膨大な帯域幅の需要が生じます)。

他のほとんどの言語では並列性が公開されていないため、見つけるのが難しく、ランタイム システムは、汎用スケジューリング プリミティブを使用して計算粒度をスケジューリングするために高い代償を払っています。アムダールの法則により、これは惨事または少なくともパフォーマンスの低下の原因であると考えています。つまり、グレインをスケジュールするための機械命令の数が作業に比べて多い場合、効率的ではありません。OTOH、スケジューリング コストを比較的低く抑えるために多くの機械語命令を使用して計算粒度を主張する場合、独立した計算粒度を見つけることができないため、スケジュールに有用な並列性がありません。したがって、PARLANSE の背後にある重要なアイデアは、グレインのスケジューリングのコストを最小限に抑え、グレインを小さくして、実際のコードで多くのグレインを見つけることができるようにすることです。

私たちは 10 年間、断続的にこれに取り組んできました。これを正しくするのは難しいです。この期間に並列言語を構築し、それらを使用/調整していない人々が、効果的な並列システムを構築する深刻な可能性を秘めているとは思えません。

于 2009-08-28T03:53:56.553 に答える
1

私はClojureが選択したモデルがとても気に入っています。Clojure は、不変データ構造とソフトウェア トランザクション メモリの組み合わせを使用します。

不変のデータ構造は、決して変更されないものです。変更されたデータを使用して構造の新しいバージョンを作成できますが、データ構造への「ポインター」を持っている場合、それが元から変更されることはありません。並行性の問題を気にせずにそのデータにアクセスできるため、これは良いことです。

ソフトウェアのトランザクショナル メモリについては、これらの回答の別の場所で説明していますが、これは、複数のスレッドがすべて何らかのデータに作用し、それらが衝突した場合、スレッドの 1 つがロールバックされて再試行されるメカニズムであると言えば十分です。これにより、衝突のリスクが存在する可能性が低い場合に、はるかに高速な速度が可能になります。

著者の Rich Hickeyによるビデオで、さらに詳しく説明されています。

于 2009-08-28T04:18:16.660 に答える
0

私はJavaを使用します-そのポータブルなので、将来のプロセッサは問題になりません。また、インターフェイス/ロジックとデータ(3層のWebアプリのようなもの)を分離するレイヤーを使用してアプリケーションをコーディングし、ライブラリとして標準のミューテックスルーチンを使用します(並列コードのデバッグは少なくなります)。Webサーバーは多くのプロセッサに非常によく対応し、マルチコアへの最も簡単なパスであることを忘れないでください。それか、データに接続された仮想プロセッサを備えた古いコネクションマシンモデルを見てください。

于 2008-09-17T04:34:56.793 に答える
0

Erlang はより「成熟したソリューション」であり、移植可能でオープン ソースです。私は Polyphonic C# をいじりましたが、毎日プログラミングする方法がわかりません。

太陽の下のほぼすべての言語/OS 用のライブラリと拡張機能があります。Google トランザクション メモリ . これは、MS からの興味深いアプローチです。

于 2008-10-23T11:18:27.063 に答える