ホームページ  >  記事  >  バックエンド開発  >  Goodbye Go インタビュアー: GMP モデル、なぜ P があるのですか?

Goodbye Go インタビュアー: GMP モデル、なぜ P があるのですか?

Golang菜鸟
Golang菜鸟転載
2023-08-08 16:31:451365ブラウズ


今日の主役は、Go インタビューの汎用 GMP モデル質問の拡張質問 (質問)、つまり「GMP モデル、なぜ」です。 P はありますか? "

質問の背後にあるさらなる検討、実際、この面接の質問の本質は次のような質問です。「GMP モデル、なぜ G と M を直接結合できないのか」 ? 追加の P もあります。とても面倒です。なぜですか。どのような問題を解決しようとしているのですか?」

この記事では、Jianyu が GM と GMP の変更の理由を探ります。モデル。

GM モデル

Go1.1 より前では、Go のスケジューリング モデルは実際には GM モデルでした。つまり、P はありませんでした。

今日は過去のデザインをレビューしていきます。

Go1.0 ソース コードの解読

何かを理解する方法の 1 つは、ソース コードを調べて、 Jianyu を使用した Go1.0.1 スケジューラーのソース コードの主要なステップ:

static void
schedule(G *gp)
{
 ...
 schedlock();
 if(gp != nil) {
  ...
  switch(gp->status){
  case Grunnable:
  case Gdead:
   // Shouldn't have been running!
   runtime·throw("bad gp->status in sched");
  case Grunning:
   gp->status = Grunnable;
   gput(gp);
   break;
  }

 gp = nextgandunlock();
 gp->readyonstop = 0;
 gp->status = Grunning;
 m->curg = gp;
 gp->m = m;
 ...
 runtime·gogo(&gp->sched, 0);
}

  • schedlock メソッドを呼び出して、グローバル ロックを取得します。
  • グローバル ロックの取得に成功したら、現在の Goroutine の状態を実行中 (スケジュール済み) から実行可能 (スケジュール可能) に変更します。
  • gput メソッドを呼び出して、現在の Goroutine 実行ステータスやその他の情報を後で使用できるように保存します。
  • nextgandunlock メソッドを呼び出して、次に実行可能な Goroutine を見つけ、他のスケジューラーが使用できるようにグローバル ロックを解放します。
  • 次に実行する Goroutine を取得したら、その実行ステータスを「実行中」に変更します。
  • runtime·gogoメソッドを呼び出して、取得したばかりの次の実行対象ゴルーチンを実行し、次のスケジュール設定に入ります。

GM モデルについて考える

Go1.0.1 のスケジューラ ソース コードを分析すると、さらに興味深い点。それがスケジューラそのもの(scheduleメソッド)であり、通常の処理ではリターン、つまりメイン処理を終了することはありません。

Goodbye Go インタビュアー: GMP モデル、なぜ P があるのですか?
G-M モデル図

彼はスケジューリング プロセスを継続的に実行します。GoroutineA が完了すると、GoroutineB の検索を開始します。B が見つかると、GoroutineB が見つかります。 A の完了したスケジューリング権が B に渡され、GoroutineB がスケジューリング、つまり実行を開始できるようになります。

もちろん、ブロックされている(Blocked)Gもあります。 G が何らかのシステム コールまたはネットワーク コールを行っていると、G はストールすることになります。この時点で、M (システム スレッド) はカーネル キューに戻され、新しいラウンドのウェイクアップを待ちます。

GM モデルの欠点

表面上、GM モデルは破壊できず、完璧であるように見えます。しかし、なぜ変更するのでしょうか?

2012 年に、Dmitry Vyukov は、「スケーラブルな Go スケジューラの設計ドキュメント」という記事を発表しましたが、これは今でも Go スケジューラに関する主要な研究記事の主な対象となっており、その記事で全体的な理由と考慮事項を説明しています。内容はこの記事を指します。

現在の Goroutine スケジューラ (Go1.0 の GM モデルを参照) は、Go で作成された同時実行プログラム、特に高スループットのサーバーや並列コンピューティング プログラムのスケーラビリティを制限します。

実装には次の問題があります:

  • 単一のグローバル ミューテックス (Sched.Lock) と集中状態管理があります:
    • mutex は、すべての goroutine 関連の操作 (作成、完了、並べ替えなど) を保護する必要があるため、深刻なロック競合が発生します。
  • Goroutine の受け渡しの問題:
    • Goroutine (G) ハンドオーバー (G.nextg): ワーカー スレッド (実行可能な goroutines M間で頻繁に引き継がれます)。
    • 上記の結果、遅延が増加し、オーバーヘッドが追加される可能性があります。すべての M は、実行可能な G、特に G を作成したばかりの M を実行できなければなりません。
  • 各 M はメモリ キャッシュ (M.mcache) を行う必要があります:
    • 過剰なリソース消費につながります (各 mcache は 2M のメモリ キャッシュとその他のキャッシュを吸収できますが、データの局所性は劣ります。
  • 頻繁なスレッドのブロック/ブロック解除:
    • syscall が存在すると、スレッドがブロックされたり、ブロックが解除されたりすることがよくあります。これにより、パフォーマンスのオーバーヘッドが大幅に増加します。

GMP モデル

GM モデルの上記の多くの問題を解決するために、Go1.1 では Dmitry Vyukov が取り組みました。 GMモデルをベースに、新たにP(プロセッサー)コンポーネントを追加。また、新しく発生した問題を解決するために Work Stealing アルゴリズムを実装しました。

Goodbye Go インタビュアー: GMP モデル、なぜ P があるのですか?

GMP モデルについては、前回の記事「Go グループの友人に尋ねられた: 制御する Goroutine の適切な数はどれくらいですか? GC とスケジューリングに影響しますか?」 』で解説されています。

# 良いと思う友人は注目してください。ここでは繰り返しません。

それによってどのような変化がもたらされますか?

P を追加するとどのような変化がもたらされますか?それについてもっと明確に話しましょう。

  • 各 P には独自のローカル キューがあり、グローバル キューへの直接の依存が大幅に減少し、その結果、ロックの競合が減少します。 GM モデルのパフォーマンス オーバーヘッドの大部分はロック競合です。

  • 各 P の相対的なバランスに基づいて、ワーク スティーリング アルゴリズムも GMP モデルに実装されています。P のローカル キューが空の場合、グローバル キューから削除したり、他の P のローカル キューから実行可能な G を盗んで実行したりして、アイドリングを減らし、リソースの使用率を向上させます。

#なぜ P

があるのか​​、現時点では、混乱している友人もいるかもしれません。ローカル キューとワーク スティーリング アルゴリズムを実装するには、それを M に直接追加してみてはいかがでしょうか? M は引き続き同様の機能を実現できます。

なぜ別の P コンポーネントを追加するのでしょうか?

M(システムスレッド)の配置と合わせて、これを行うと以下の問題が発生します。

一般的に、M の数は P よりも多くなります。 Go と同様に、M の数の最大制限は 10000 で、デフォルトの P の数は CPU コアの数です。さらに、M の特性により、つまり、M をブロックするシステム ブロッキング コールが存在しても十分ではない場合、M は増加し続けます。
  • M が増加し続ける場合、ローカル キューが M にマウントされている場合、ローカル キューもそれに応じて増加することを意味します。ローカルキューの管理が複雑になり、Work Stealing のパフォーマンスが大幅に低下するため、これは明らかに不合理です。
  • #M がシステム コールによってブロックされた後、ブロックされてすぐにすべてが停止するのではなく、未実行のタスクを他のタスクに割り当てて実行を継続したいと考えています。
  • したがって、M を使用するのは不合理です。その場合、新しいコンポーネント P を導入し、ローカル キューを P に関連付けることで、この問題をうまく解決できます。

概要

今日の記事では、Go 言語スケジューラ全体のいくつかの歴史的状況、原因分析、解決策の説明を組み合わせます。

「GMP モデル、なぜ P があるのですか?」 この質問はシステム設計の理解に似ています。なぜなら、多くの人が面接に対処するために GMP モデルを暗記したり、インスタント スタイルでそれを実行したりするからです。そして、その背後にある本当の理由を理解することが、私たちが学び、理解する必要があることなのです。

何が起こっているのか、なぜそれが起こっているのかを知ることによってのみ、状況を打破することができます。

以上がGoodbye Go インタビュアー: GMP モデル、なぜ P があるのですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はGolang菜鸟で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。