マルチコアで並列プログラムを書くための言語としてのErlangには、最近大きな関心が寄せられています。私は、Erlangのメッセージパッシングモデルはスレッドのような支配的な共有メモリモデルよりもプログラムが簡単であると人々が主張するのを聞いたことがあります。
逆に、高性能コンピューティングコミュニティでは、主要な並列プログラミングモデルはMPIであり、これもメッセージパッシングモデルを実装しています。しかし、HPCの世界では、このメッセージパッシングモデルは一般的にプログラムするのが非常に難しいと考えられており、OpenMPやUPCなどの共有メモリモデルの方がプログラムしやすいと人々は主張しています。
ITおよびHPCの世界では、メッセージパッシングと共有メモリの認識にこのような違いがあるのはなぜでしょうか。 ErlangとMPIがErlangスタイルのメッセージパッシングをMPIよりもはるかに簡単にするメッセージパッシングを実装する方法に根本的な違いがあるのでしょうか。それとも他の理由がありますか?
私はこれまでのすべての答えに同意しますが、完全には明らかにされていない重要なポイントは、MPIが難しいと考えられ、Erlangがドメインとモデルを一致させることの1つの理由です。
Erlangは、ローカルメモリ、非同期メッセージパッシング、およびすべてのスレッドが到達できる何らかの形式のグローバルデータベースを使用することによって解決される共有状態の概念に基づいています。大量のデータを移動しないアプリケーション用に設計されています。調整が必要な100kの別々のノードに爆発することは想定されていません。
MPIはローカルメモリとメッセージの受け渡しに基づいており、データを移動することがドメインの重要な部分である問題を対象としています。高性能コンピューティングとは、データセットを問題として扱い、それを多数のコンピューティングリソース間で分割することです。そして、データを分散を念頭に置いて明示的に配布する必要があるため、メッセージパッシングシステムではそれはかなり大変な作業です。基本的に、MPIは、共有メモリが拡張されていないという汚い容認と見なすことができます。そしてそれは100k以上のプロセッサにまたがる高性能計算をターゲットにしています。
Erlangは、可能な限り最高のパフォーマンスを達成しようとしているのではなく、自然な並列問題を自然なスレッドに分解しようとしています。 MPIとは全く異なる種類のプログラミングタスクを念頭に置いて設計されています。
そのため、Erlangは、まったく異なる(そしてある程度ある程度本質的に難しい)問題を対象としたMPIよりも、pthreadや他のローカルの異種スレッドソリューションとの比較に最も適しています。
Erlangでの並列処理まだです実装するのはかなり難しいです。それによって、私はあなたがまだあなたの問題を分割する方法を考え出す必要があることを意味しますが、CまたはC ++のMPIライブラリと比較するとこの困難を緩和するいくつかの小さなことがあります。
まず、Erlangのメッセージパッシングは第一級の言語機能であるため、構文上の糖がそれをより簡単にします。
また、ErlangライブラリはすべてErlangのメッセージパッシングを中心に構築されています。この支持構造はあなたに並行処理土地への後押しを与えるのを助けます。を見てください。OTPの構成要素gen_server、gen_fsm、gen_eventのように。これらはあなたのプログラムが並列になるのを助けることができる構造を非常に使いやすいです。
私はそれが、言語自体の特定の機能ではなく、他のMPI実装とアーランのメッセージ受け渡しを区別するために利用可能な標準ライブラリのより堅牢性であると思います。
通常、HPCでの並行性は、大量のデータを処理することを意味します。この種の並列処理は、データ並列処理なぜなら、オペレーティングシステムはタスクのスケジューリングや配置など、メッセージパッシングパラダイムを使用する場合は自分で実装する必要があるからです。
対照的に、Erlangは以下に対処するように設計されました。タスク並列処理電話システムでは、限られた量の通信と、フォールトトレランスと回復のための強力な要件だけで、さまざまなコードを同時に実行する必要があります。
このモデルは、ほとんどの人がPThreadを使っているものと似ています。 HPCアプリケーションは、ワーカー間で交換しなければならない大量のデータに対してもほぼ同じことを実行しますが、Webサーバーのような各要求を異なるスレッドで処理できるアプリケーションに適しています。
MPIを使ってプログラミングしているときや、Erlangを使ってプログラミングしているときには、考え方と関係があると思います。たとえば、MPIは言語に組み込まれていませんが、Erlangはメッセージの受け渡しをサポートしています。もう1つの考えられる理由は、単にメッセージを送受信することと、ソリューションを並行実行単位に分割することとの間の切断です。
Erlangでは、関数呼び出しから関数呼び出しへデータが実際に圧縮される関数型プログラミングフレームで考えることを強いられます - そして受信は言語の通常の構成のように見える積極的な行為です。これにより、実際に実行している計算とメッセージを送受信する動作との間の密接な関係が得られます。
一方MPIでは、実際のメッセージの受け渡しについてだけ考える必要がありますが、実際の作業の分解については考えられません。この考え方の枠組みでは、コード内でソリューションとメッセージングインフラストラクチャを記述することの間にコンテキストの切り替えがいくらか必要です。
議論を続けることができますが、一般的な見解は、メッセージパッシングのための構成が実際に使用しているプログラミング言語とパラダイムに組み込まれている場合、通常「解決される」よりも解決策を表現するためのより良い手段です。 "または言語へのアドオンとして存在します(ライブラリまたは拡張機能の形式で)。
ITおよびHPCの世界では、メッセージパッシングと共有メモリの認識にこのような違いがあるのはなぜでしょうか。 ErlangとMPIがErlangスタイルのメッセージパッシングをMPIよりもはるかに簡単にするメッセージパッシングを実装する方法に根本的な違いがあるのでしょうか。それとも他の理由がありますか?
その理由は、単に並列処理と並行処理です。 Erlangは並行プログラミングのために飼育されています。 HPCは、すべて並列プログラミングに関するものです。これらは関連していますが、目的は異なります。
並行プログラミングは、非常に非決定論的な制御フローによって非常に複雑になり、待ち時間がしばしば重要な目的となります。 Erlangが不変のデータ構造を使用すると、並行プログラミングが非常に簡単になります。
並列プログラミングははるかに単純な制御フローを持ち、その目的は待ち時間ではなく最大総スループットに関するものです。効率的なキャッシュの使用は、ここではもっと重要です。これはErlangと不変のデータ構造の両方を大部分不適切にします。共有メモリの変更は扱いやすく、この文脈ではかなり優れています。実際、キャッシュコヒーレンスはハードウェアアクセラレーションによるメッセージの受け渡しを可能にしています。
最後に、これらの技術的な違いに加えて、政治的な問題もあります。 Erlangは、Erlangがマルチコアに関連していない場合に関連性があると見せかけて、マルチコアの宣伝に乗り込もうとしています。特に、高いスケーラビリティを売り込んでいるため、絶対的なパフォーマンスも考慮することが不可欠です。 Erlangは、1つのコア上での絶対的なパフォーマンスの低下から、任意の数のコア上での絶対的なパフォーマンスの低下まで、簡単に拡張できます。あなたが想像できるように、それはHPC共同体を感動させません(しかし、それは多くのひどく並行なコードのために十分です)。
MPIとOpenMP / UPCの関係:MPIでは、問題を細かく分割してデータを移動させる責任があります。 OpenMP / UPCでは、「すべてのデータが存在する」ので、ポインタを間接参照するだけです。 MPIの利点は、32-512 CPUクラスタが32-512 CPUシングルマシンよりはるかに安価であるということです。また、MPIを使用すると、アルゴリズムを設計するときに費用が前払いされます。システムがNUMAを使用している場合(およびすべての大規模システムが使用している場合)、OpenMP / UPCは実行時に発生する待ち時間を隠すことができます。
この記事では実際によく説明されています。小さなデータをまとめて送信する場合はErlangが最適です。MPIはより複雑なものに対してははるかに優れています。またErlangモデルは理解しやすいです:-)