[解決済み] 技術的に、なぜErlangのプロセスはOSのスレッドよりも効率的なのですか?
質問
Erlangの特徴
から Erlang プログラミング (2009):
Erlangの並行処理は高速でスケーラブルです。Erlangのプロセスは軽量で、Erlang仮想マシンはプロセスを作成するたびにOSスレッドを作成するわけではありません。プロセスは仮想マシン内で作成、スケジューリング、処理され、オペレーティングシステムに依存しません。その結果、プロセスの作成時間はマイクロ秒のオーダーで、同時に存在するプロセスの数には依存しません。これをJavaやC#と比較してみてください。JavaではプロセスごとにOSのスレッドが作成されます:非常に競争力のある比較になりますが、Erlangはどちらの言語も大きく凌駕しています。
より Erlangの並行処理指向プログラミング (pdf) (スライド) (2003):
Erlangのプロセス作成にかかる時間は、2,500プロセスまでは1μsと一定ですが、それ以降は30,000プロセスまで約3μsに増加することがわかります。図の上部にJavaとC#のパフォーマンスを示しています。プロセス数が少ない場合、プロセスの作成に約300µsかかります。2,000以上のプロセスを作成することは不可能です。
3万プロセスまでなら、2つのErlangプロセス間でメッセージを送信する時間は約0.8μsであることがわかります。C#では最大プロセス数(約1800プロセス)まで、1メッセージあたり約50µsかかりました。Javaはさらに悪く、100プロセスまでは1メッセージあたり約50µsで、その後1000プロセスくらいになると1メッセージあたり10msと急激に増加しました。
私の考え
なぜErlangのプロセスが新しいプロセスを生成するのにとても効率的で、プロセスあたりのメモリフットプリントがずっと小さいのか、技術的に完全に理解できていません。OSとErlang VMの両方がスケジューリングやコンテキストスイッチをしなければならず、レジスタの値などを追跡しなければならないからです。
単純に、なぜOSのスレッドはErlangのプロセスと同じように実装されないのでしょうか?もっと何かサポートしなければならないのでしょうか?そしてなぜより大きなメモリフットプリントが必要なのでしょうか?そしてなぜスレッドの起動や通信が遅いのでしょう?
技術的に、スポーンや通信に関して、なぜErlangのプロセスの方がOSのスレッドよりも効率的なのでしょうか?そしてなぜOSのスレッドは同じように効率的に実装・管理できないのでしょうか?そしてなぜOSのスレッドは大きなメモリフットプリントがあり、さらにスポーンや通信が遅いのでしょうか?
もっと読む
- Erlang VMの内部 SMPにフォーカスして (2008)
- JavaとErlangの並行処理 (pdf) (2004)
- JavaにおけるスレッドとErlangにおけるプロセスのパフォーマンス測定 (1998)
解決方法は?
いくつかの要因があります。
- ErlangのプロセスはOSのプロセスではありません。Erlang VMによって軽量な協調スレッドモデルを使って実装されています(Erlangレベルではプリエンプティブですが、協調的にスケジュールされたランタイムのコントロールの下にあります)。これはコンテキストの切り替えがとても安く、既知の制御されたポイントで切り替えるだけなので、CPUの状態(通常、SSEやFPUレジスタ、アドレス空間マッピングなど)全体を保存する必要がないことを意味します。
- Erlangプロセスは動的に割り当てられたスタックを使います。スタックはとても小さく始まり、必要に応じて大きくなります。これによって利用可能なRAMを使い切ることなく、何千、何百万ものErlangプロセスを生成することができます。
- Erlangはかつてシングルスレッドでした。つまり、プロセス間のスレッドセーフを確保する必要がありませんでした。現在ではSMPをサポートしていますが、同じスケジューラ/コア上のErlangプロセス間のやりとりはまだとても軽量です(コアごとに個別のランキューがあります)。
関連
-
コレクションが変更されたため、列挙操作が実行できない場合がある Error
-
[解決済み] Nodejsのシングルスレッドの意味するところ
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] プロセスとスレッドの違いは何ですか?
-
[解決済み] レースコンディションとは何ですか?
-
[解決済み] スレッドは何本までならOK?
-
[解決済み] スレッドセーフとは何ですか?
-
[解決済み] Powershellでコマンドを並列に実行することはできますか?
-
[解決済み] コンパイル時の-pthreadと-lpthreadの違いについて
-
[解決済み] ノンブロッキングI/Oは、マルチスレッドのブロッキングI/Oより本当に速いのか?どのように?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Nodejsのシングルスレッドの意味するところ
-
[解決済み] レースコンディションとは何ですか?
-
[解決済み] デッドロックとライブロックの違いは何ですか?
-
[解決済み] 再帰的ロック (Mutex) vs 非再帰的ロック (Mutex)
-
[解決済み] 技術的に、なぜErlangのプロセスはOSのスレッドよりも効率的なのですか?
-
[解決済み] デッドロックとは何ですか?
-
[解決済み] マルチスレッドに代わるNode JSを把握する
-
[解決済み] Powershellでコマンドを並列に実行することはできますか?
-
[解決済み] コンパイル時の-pthreadと-lpthreadの違いについて
-
[解決済み] 条件付き変数とセマフォの比較