これは私の前の質問の延長です
nix/linuxソケットのブロッキングモードはどのように機能しますか?
私が今インターネットから収集したもの、つまりブロッキング呼び出しを呼び出すすべてのプロセスは、スケジューラーがそれをブロック解除する理由を見つけるまでスリープ状態になります。理由は、バッファが空の場合からバッファがいっぱいの場合、その他の条件までさまざまです。
しかし、これはリアルタイムへの効率的な方法である可能性がありますか?ハード/ファームリアルタイムアプリケーションとしましょう。ブロック解除条件が真の場合、プロセスはブロック解除されないため、スケジューラーがCPUスライスを提供し、ブロック解除条件が両方とも真の場合。
応答性の高いソリューションが必要であるかのように、この「スピンロック」または「ビジー待機」が正しい方法であるとは思わず、CPUスライスが無駄になり、システム全体が応答しなくなるか、応答性が低下する可能性があります。
誰かがこの相反する考えをクリアしてくれませんか。
スケジューラーがあなたを起こすまでスリープ状態になるのは、通常の/好ましいことです。
スピニング(眠らずに待つ別の方法)はあまり一般的ではなく、次のような効果があります。
CPUをビジー状態に保ち、他のスレッドがCPUを使用できないようにします(回転しているスレッドがタイムスライスを終了してプロンプトが表示されるまで)
あなたが待っていることが起こった瞬間に回転を止めることができます(あなたはそのイベントを継続的にチェックしていて、あなたはすでに起きているので、目覚めるのにかかる時間をとる必要がないからです)
スリープ状態になり、再びウェイクアップするために必要なCPU命令を呼び出さない
遅延の長さが非常に短い場合(たとえば、遅延が100 CPU命令の実行にかかる時間だけである場合)、スピンはスリープ状態になるよりも効率的(合計CPUが少ない)になる可能性があります。 。
A スピンロック 目的のイベントが発生しない間、リソースの継続的な浪費のためにCPUとポーリングされたリソースパスを焼きます。
A ブロッキング 最も重要な操作は、CPUと関連するリソースパスを除外し、目的のイベントが予期されるリソースに何らかの形式のwait
をインストールすることによって異なります。
マルチタスクまたはマルチスレッド/プロセッサ環境(現在は長い間通常のケース)では、目的のイベントが到着していないときに他の操作が可能であるため、CPUとリソースのアクセスパスを焼き付けると、処理能力と時間の無駄が大きくなります。
ハイパースレッディングシステムがある場合(質問で言及しているように)、CPUスレッドがスライスされる粒度が非常に高いことに注意することが重要です。また、ブロックする傾向のあるすべてのイベントが発生するのに十分な時間がかかり、ブロックを解除する前に余分に待たなければならなかった小さなタイムスライスを補うために首を突き出します。
おもう J-16
sポイントは、スリープ状態の(ブロックされた)スレッドが、ブロックされた状態のときにコードとデータスペースを未使用のままにしておく状態を指します。これにより、システムがリソース(データ/コードキャッシュなど)を放棄する可能性があり、ブロックが解放されたときにリソースを補充する必要があります。したがって、条件に応じて、ブロックはより多くのリソースの浪費に影響を与える可能性があります。
これも有効なメモであり、設計と実装で確認する必要があります。
しかし、ほとんどの場合、ブロッキングは通常、スピンロックよりも優れています。
アプリケーションのユースケースで、条件の切り替えが数CPUサイクルを消費するよりもコストがかかる場合は、条件が短時間で満たされることが保証されるため、ビジーウェイトが適している可能性があります。
それ以外の場合は、スリープまたはcond_wait()
ingによってCPUを強制的に放棄できます。
強制的なコンテキストスイッチアウトについて考えることができるもう1つのシナリオは、次のとおりです。
while(condition)
sleep(0);
まず第一に、あなたは誤解を持っています:
通話のブロックは、「ビジーウェイト」や「スピンロック」ではありません。ブロッキング呼び出しはスリープ可能です。つまり、CPUは他のタスクで動作し、CPUが無駄になることはありません。
通話のブロックに関する質問について
通話のブロックは簡単です。理解しやすく、開発しやすく、デバッグしやすいのです。
しかし、それらはリソースを大量に消費します。スレッドを使用しないと、他のクライアントがブロックされます。スレッドを使用する場合、各スレッドはメモリやその他のシステムリソースを消費します。十分なメモリがある場合でも、スレッドを切り替えるとキャッシュがコールドになり、パフォーマンスが低下します。
これはトレードオフです-より速い開発と保守性?またはスケーラビリティ。
ここでは他の回答を通じて十分な説明が提供されているので、要点を述べようと思います。そうです、これらすべての回答から学ぶことで、全体像がわかると思います。 ---
私によると、トレードオフは、システムの応答性とスループットの間でなければなりません。
応答性-2つの観点から考えることができます
システムの応答性については、呼び出しをブロックすることが最善の方法だと思います。ブロックされた状態でブロッキング呼び出しが行われると、CPUがレディキュー内の他のプロセスに渡されるためです。
そしてもちろん、特定のプロセスまたはプロセスごとの応答性については、ビジー待機/スピンロックモデルを検討します。
ここでも、全体的なシステムの応答性を向上させるために、スケジューラーのタイムスライス(細粒度)を減らすことはできません。これは、CPUを浪費するためです。コンテキストスイッチのリソース。したがって、システムのスループットは大幅に減少します。もちろん、ブロックされた呼び出しはCPUスライスを消費せず、レディキュー内の他の/次のプロセスにそれを与えるため、ブロックモデルがシステムのスループットを向上させることは明らかです。
全体的な応答性とスループットに影響を与えずに、プロセスごとの応答性を念頭に置いてシステムを設計するのが最善だと思います。複雑さを追加しない場合は、優先順位の逆転の問題を考慮して、優先順位ベースのスケジューラを実装します。気になります:)。