ご存知のとおり、Linux はマルチタスクをサポートするオペレーティング システムであり、同時に実行できるタスクの数は CPU の数をはるかに超えています。もちろん、これらのタスクは実際には (単一の CPU に対して) 同時に実行されているわけではありませんが、システムはこれらのタスクに短時間順番に CPU を割り当て、複数のタスクが同時に実行されているような錯覚を引き起こすためです。 。
各タスクを実行する前に、CPU はタスクをどこにロードして開始するかを認識する必要があります。これは、システムが CPU の レジスタ と プログラム カウンタ を事前に設定する必要があることを意味します。
CPU レジスタは、CPU に組み込まれた小さいながらも非常に高速なメモリです。プログラム カウンタは、CPU によって現在実行されている命令の位置、または次に実行される命令の位置を保存するために使用されます。
どちらもタスクを実行する前にCPUに必要な環境であるため、「CPUコンテキスト」と呼ばれます。下の図を参照してください:
CPU コンテキストが何であるかがわかったので、CPU コンテキストの切り替えについても簡単に理解できると思います。 「CPU コンテキストの切り替え」とは、前のタスクの CPU コンテキスト (CPU レジスタとプログラム カウンタ) を保存し、新しいタスクのコンテキストをこれらのレジスタとプログラム カウンタにロードし、最後にプログラム カウンタにジャンプすることを指します。
これらの保存されたコンテキストはシステム カーネルに保存され、タスクの実行が再スケジュールされたときに再度ロードされます。これにより、タスクの元の状態が影響を受けず、タスクが継続的に実行されているように見えます。
CPU コンテキストの切り替えは、CPU レジスターとプログラム カウンタ値を更新するだけであり、これらのレジスターはタスクを高速に実行するように設計されているのに、なぜ CPU のパフォーマンスに影響するのでしょうか?
この質問に答える前に、これらの「タスク」が何なのか考えたことはありますか?タスクは プロセス または スレッド であると言えるかもしれません。はい、プロセスとスレッドが最も一般的なタスクですが、それ以外にも他の種類のタスクがあります。
忘れないでくださいハードウェア割り込みも一般的なタスクであり、ハードウェア トリガー信号によって割り込みハンドラーが呼び出されます。
したがって、CPU コンテキスト スイッチには少なくとも 3 つの異なるタイプがあります。
1つずつ見ていきましょう。
Linux は、特権レベルに応じてプロセスの実行空間をカーネル空間とユーザー空間に分割します。これらは、それぞれ下図。
カーネル スペース
ユーザー スペース ( カーネルにトラップする必要があります。
別の観点から見ると、プロセスはユーザー空間とカーネル空間の両方で実行できます。プロセスが ユーザー空間カーネル空間に入る場合は、##と呼ばれます。プロセスの#kernelstate。 ユーザーモードからカーネルモードへの変換は、システムコールを通じて完了する必要があります。たとえば、ファイルの内容を表示するには、次のシステム コールが必要です:
元の保存されたユーザー状態を復元し、ユーザー空間に切り替えてプロセスの実行を続行する必要があります。
コンテキストスイッチ 特権モードスイッチと呼ばれます。しかし実際には、システムコールの処理中に CPU コンテキストの切り替えも避けられません。
プロセスコンテキストの切り替えとシステムコールの比較 スタック、グローバル変数などのユーザー空間リソースだけでなく、カーネル スタックも含まれます。および およびその他のカーネル空間ステータスを登録します。
つまり、 プロセスコンテキストの切り替え :
現在のプロセスのカーネル状態と CPU レジスタを保存する前に、プロセスの仮想メモリ、スタックなどを保存し、次のプロセスのカーネル状態をロードする必要があります。
了解這些場景是非常有必要的,因為一旦上下文切換出現效能問題,它們就是幕後殺手。 #執行緒與行程最大的差別在於,執行緒是任務排程的基本單位,而行程是資源取得的基本單位。 說穿了,核心中所謂的任務調度,實際的調度物件是線程;而進程只提供線程虛擬記憶體和全域變數等資源。所以,對於線程和進程,我們可以這樣理解: 這樣,執行緒的上下文切換其實可以分成兩種情況: 顯然,同一個行程內的執行緒切換比切換多個行程消耗的資源少。這也是多執行緒替代多進程的優勢。 #除了前面兩種上下文切換之外,還有另一個場景也輸出 CPU 上下文切換的,那就是中斷。 為了快速回應事件,硬體中斷會中斷正常的調度和執行過程,進而呼叫中斷處理程序。 中斷其他行程時,需要儲存行程的目前狀態,以便中斷後行程仍能從原始狀態復原。 與行程上下文不同,中斷上下文切換不涉及行程的使用者態。因此,即使中斷進程中斷了處於使用者狀態的進程,也不需要保存和復原進程的虛擬記憶體、全域變數等用戶態資源。 另外,和行程上下文切換一樣,中斷上下文切換也會消耗 CPU。過多的切換次數會消耗大量的 CPU 資源,甚至嚴重降低系統的整體效能。因此,當您發現中斷過多時,您需要注意排查它是否會對您的系統造成嚴重的效能問題。 綜上所述,無論哪種場景導致上下文切換,你都應該知道: CPU 上下文切換是保證 Linux 系統正常運作的核心功能之一,一般不需要我們特別注意。 但是過多的上下文切換會消耗 CPU 的時間來保存和恢復寄存器、核心堆疊、虛擬記憶體等數據,從而縮短進程的實際運行時間,導致系統整體效能顯著下降。
それでは、上記のシステムコール中に CPU コンテキストの切り替えが発生するのでしょうか?もちろん。 :ファイルを開く
: ファイルの内容を読み取ります
: ファイルの内容を出力ファイル (標準出力を含む) に書き込みます
:ファイルを閉じる
システムコールプロセスは通常、
それでは、プロセス コンテキストの切り替えとシステム コールの違いは何でしょうか?まず、プロセスはカーネルによって管理され、プロセスの切り替えはカーネル モードでのみ発生します。したがって、プロセス コンテキストには、仮想メモリ
、Tsuna のテスト レポートによると、各コンテキストの切り替えには数十ナノ秒からマイクロ秒の CPU 時間が必要です。この時間は、特に多数のプロセス コンテキストの切り替えの場合にかなりの時間がかかり、CPU がレジスタ、カーネル スタック、仮想メモリなどのリソースの保存と復元に多くの時間を費やしやすくなります。これはまさに前回の記事で説明したことであり、負荷平均を上昇させる重要な要因です。
sleep
函數自動掛起自己時,自然會被重新調度。 線程上下文切換
中斷上下文切換
結論
以上がLinux CPU でのコンテキスト切り替えの調査の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。