8

私は最近、ノンブロッキング IO と驚異的な速度で知られる V8 上の JavaScript ライブラリである node.js について学び始めました。

私の理解では、ノードは IO が応答するのを待ちませんが、未完了の操作をチェックし続け、IO が応答するとすぐにそれらを続行/完了するイベント ループ (ゲーム ループに似ています) を実行します。ノードのパフォーマンスは Apache HTTPD と比較され、ノードはより少ないメモリを使用しながら大幅に高速化されました。

Apache について読んだ場合、ユーザーごとに 1 つのスレッドを使用していることがわかります。これにより、大幅に速度が低下すると思われます。ここで私の質問が表示されます。

スレッドを、ノードがイベント ループで内部的に行うことと比較すると、類似点が見え始めます。どちらも、リソースの応答を待機する未完了のプロセスの抽象化であり、操作が定期的に進行したかどうかをチェックし、その後、リソースを占有しないようにします。 CPU を一定時間 (少なくとも、良いブロッキング API は再チェックする前に数ミリ秒間スリープすると思います)。

では、スレッドをこれほどまでに悪化させている印象的で重大な違いはどこにあるのでしょうか?

4

2 に答える 2

10

ここでの違いは、コンテキストの切り替えです。OS によるスレッドのスワップには、次のものが必要です。

  • 命令ポインターの保存 (CPU によって行われる)
  • CPU レジスタの保存 (スレッドがブロッキング呼び出しを行った場合は必要ないかもしれませんが、プリエンプトされた場合は必要です)
  • 呼び出しスタックを交換します。スタックが同じ仮想メモリ空​​間に存在する場合でも、これは少なくとも1 つの書き込みといくつかの読み取りであり、マイクロスレッド (ファイバー) にも適用されます。
  • 別のプロセスへのスワップ、カーネル モードへのスワップ、仮想メモリ テーブルの更新、およびユーザー モードへの復帰の場合。

イベント キューの場合:

  • 状態が更新されます。これは、いずれにしても発生する必要があります。
  • イベント ハンドラが返されます。コール スタックを交換する代わりに、現在のコール スタックがポップされます。
  • イベント キューで保留中の要求がチェックされます。保留中の要求がない場合にのみ、アプリケーションは待機します。これは、(OP で提案されているように) 繰り返しスリープするか、(より良い) イベント キューへのブロッキング呼び出しを行うことで実行できます。イベント キュー (TCP ソケットのセットなど) が OS によって管理されている場合、OS は新しいイベントをアプリケーションに通知する責任があります (ソケットはより多くのデータを受け入れることができます)。

サーバーの負荷が高い場合、イベント キューの唯一のオーバーヘッドは、ハンドラーのリターン、キューの読み取り、およびハンドラーの呼び出しです。スレッド化されたアプローチでは、スレッドのスワップによる追加のオーバーヘッドがあります。

また、 PSTで言及されているように、スレッド化されたアプローチではロックが必要になります。ロック自体は安価ですが、他のスレッドによってリソースが解放されるのを待つと、待機中のスレッドが続行できないため、追加のコンテキスト切り替えが必要になります。スレッドがロックを取得するためにスワップインされ、別のリソースもロックする必要があるため、数クロックサイクル後にスワップアウトされることさえあります。OS によって行われる処理 (少なくともトレッド キューの読み取りとコール スタックのスワップ) と、スレッドによって行われる処理 (呼び出しから戻って別の呼び出しを行う) を比較します。

于 2012-10-28T03:44:19.840 に答える
0

ある面では、その言語に固有のスレッド化の実装に依存します。ただし、一般に、コストのかかる部分はスレッドの作成であり、スレッドの実行ではありません。そのため、一部の言語 (.Net など) は、スレッドのスレッド プールを配置したままにしておくため、本質的に既に作成されているスレッド プールを取得して、コストを抑えることができます。

スレッドの問題は、教授が私に言ったことによると、すべての言語には Thread.Yield() 関数と同等のものがありますが、実際には誰もそれを利用していないということです。そのため、遭遇するすべてのスレッドはスケジューリングにおいて非常に積極的であり、ミューテックスとセパフォの間であらゆる種類の戦争を引き起こします。一部のスレッドは、使用される攻撃性のレベルが原因で、実際には実行されず、それ自体が問題です。

スレッドの利点は、機能の増加を犠牲にして、GUI ループなどの他のループから機能をオフロードすることです。私の知る限り、イベントはまだ単一のスレッドで実行されます (特に指示がない限り)。

于 2012-10-28T03:32:43.280 に答える