Linux CPU でのコンテキスト切り替えの調査

WBOY
リリース: 2024-02-05 13:06:10
転載
620 人が閲覧しました

ご存知のとおり、Linux はマルチタスクをサポートするオペレーティング システムであり、同時に実行できるタスクの数は CPU の数をはるかに超えています。もちろん、これらのタスクは実際には (単一の CPU に対して) 同時に実行されているわけではありませんが、システムはこれらのタスクに短時間順番に CPU を割り当て、複数のタスクが同時に実行されているような錯覚を引き起こすためです。 。

CPU コンテキスト

各タスクを実行する前に、CPU はタスクをどこにロードして開始するかを認識する必要があります。これは、システムが CPU の レジスタ プログラム カウンタ を事前に設定する必要があることを意味します。

CPU レジスタは、CPU に組み込まれた小さいながらも非常に高速なメモリです。プログラム カウンタは、CPU によって現在実行されている命令の位置、または次に実行される命令の位置を保存するために使用されます。

どちらもタスクを実行する前にCPUに必要な環境であるため、「CPUコンテキスト」と呼ばれます。下の図を参照してください:

探讨 Linux CPU 的上下文切换

CPU コンテキストが何であるかがわかったので、CPU コンテキストの切り替えについても簡単に理解できると思います。 「CPU コンテキストの切り替え」とは、前のタスクの CPU コンテキスト (CPU レジスタとプログラム カウンタ) を保存し、新しいタスクのコンテキストをこれらのレジスタとプログラム カウンタにロードし、最後にプログラム カウンタにジャンプすることを指します。

これらの保存されたコンテキストはシステム カーネルに保存され、タスクの実行が再スケジュールされたときに再度ロードされます。これにより、タスクの元の状態が影響を受けず、タスクが継続的に実行されているように見えます。

CPU コンテキスト スイッチの種類

CPU コンテキストの切り替えは、CPU レジスターとプログラム カウンタ値を更新するだけであり、これらのレジスターはタスクを高速に実行するように設計されているのに、なぜ CPU のパフォーマンスに影響するのでしょうか?

この質問に答える前に、これらの「タスク」が何なのか考えたことはありますか?タスクは プロセス または スレッド であると言えるかもしれません。はい、プロセスとスレッドが最も一般的なタスクですが、それ以外にも他の種類のタスクがあります。

忘れないでくださいハードウェア割り込みも一般的なタスクであり、ハードウェア トリガー信号によって割り込みハンドラーが呼び出されます。

したがって、CPU コンテキスト スイッチには少なくとも 3 つの異なるタイプがあります。

  • プロセスコンテキストの切り替え
  • スレッドコンテキストの切り替え
  • 割り込みコンテキストスイッチ

1つずつ見ていきましょう。

プロセスコンテキストの切り替え

Linux は、特権レベルに応じてプロセスの実行空間をカーネル空間とユーザー空間に分割します。これらは、それぞれ下図。 カーネル スペース

(
    リング 0
  • ) には最高の権限があり、すべてのリソースに直接アクセスできます ユーザー スペース (
  • リング 3
  • ) は、制限されたリソースのみにアクセスでき、メモリなどのハードウェア デバイスに直接アクセスできません。これらの特権リソースにアクセスするには、 システム コール を介して カーネルにトラップする必要があります。 別の観点から見ると、プロセスはユーザー空間とカーネル空間の両方で実行できます。プロセスが ユーザー空間
  • で実行されている場合、それはプロセスの
ユーザー状態探讨 Linux CPU 的上下文切换と呼ばれ、

カーネル空間に入る場合は、##と呼ばれます。プロセスの#kernelstate

ユーザーモードからカーネルモードへの変換は、システムコールを通じて完了する必要があります。たとえば、ファイルの内容を表示するには、次のシステム コールが必要です:

  • open():ファイルを開く
  • read(): ファイルの内容を読み取ります
  • write(): ファイルの内容を出力ファイル (標準出力を含む) に書き込みます
  • close():ファイルを閉じる
それでは、上記のシステムコール中に CPU コンテキストの切り替えが発生するのでしょうか?もちろん。

これには、最初に元のユーザー モード命令の場所を CPU レジスタに保存する必要があります。次に、カーネル モード コードを実行するには、CPU レジスタをカーネル モード命令の新しい場所に更新する必要があります。最後に、カーネル状態にジャンプして、カーネル タスクを実行します。

その後、システム コールが終了した後、CPU レジスタは

元の保存されたユーザー状態を復元し、ユーザー空間に切り替えてプロセスの実行を続行する必要があります。

したがって、システム コール中に、実際には 2 つの CPU コンテキスト スイッチが存在します。

ただし、システム コールの処理にはプロセスの切り替えや、仮想メモリなどのシステム リソースの切り替えは含まれないことに注意してください。これは、通常「プロセス コンテキストの切り替え」と呼ばれるものとは異なります。プロセス コンテキストの切り替えとは、システム コール中は常に同じプロセスが実行されている間に、あるプロセスから別のプロセスに切り替えることを指します。
システムコールプロセスは通常、

コンテキストスイッチ

ではなく、

特権モードスイッチと呼ばれます。しかし実際には、システムコールの処理中に CPU コンテキストの切り替えも避けられません。 プロセスコンテキストの切り替えとシステムコールの比較

それでは、プロセス コンテキストの切り替えとシステム コールの違いは何でしょうか?まず、プロセスはカーネルによって管理され、プロセスの切り替えはカーネル モードでのみ発生します。したがって、プロセス コンテキストには、仮想メモリ

スタックグローバル変数などのユーザー空間リソースだけでなく、カーネル スタックも含まれます。および およびその他のカーネル空間ステータスを登録します。 つまり、 プロセスコンテキストの切り替え

システムコール以外の手順が 1 つあります

: 現在のプロセスのカーネル状態と CPU レジスタを保存する前に、プロセスの仮想メモリ、スタックなどを保存し、次のプロセスのカーネル状態をロードする必要があります。

Tsuna のテスト レポートによると、各コンテキストの切り替えには数十ナノ秒からマイクロ秒の CPU 時間が必要です。この時間は、特に多数のプロセス コンテキストの切り替えの場合にかなりの時間がかかり、CPU がレジスタ、カーネル スタック、仮想メモリなどのリソースの保存と復元に多くの時間を費やしやすくなります。これはまさに前回の記事で説明したことであり、負荷平均を上昇させる重要な要因です。

それでは、プロセスが CPU 上で実行されるようにスケジュール/切り替えされるのはいつですか?実際には、多くのシナリオがあります。それらを要約してみましょう:
  • 當一個行程的 CPU 時間片用完時,它會被系統掛起,並切換到其他等待 CPU 運作的行程。
  • 當系統資源不足(如記憶體不足)時,直到資源充足之前,進程無法運作。此時進程也會被掛起,系統會調度其他進程運作。
  • 當一個行程透過 sleep 函數自動掛起自己時,自然會被重新調度。
  • 當優先權較高的進程運行時,為了確保高優先權進程的運行,當前進程會被高優先權進程掛起運行
  • 當硬體中斷發生時,CPU 上的程序會被中斷掛起,轉而執行核心中的中斷服務程序。

了解這些場景是非常有必要的,因為一旦上下文切換出現效能問題,它們就是幕後殺手。

線程上下文切換

#執行緒與行程最大的差別在於,執行緒是任務排程的基本單位,而行程是資源取得的基本單位。

說穿了,核心中所謂的任務調度,實際的調度物件是線程;而進程只提供線程虛擬記憶體和全域變數等資源。所以,對於線程和進程,我們可以這樣理解:

  • 當一個行程只有一個執行緒時,可以認為一個行程等於一個執行緒
  • 當一個行程有多個執行緒時,這些執行緒共享相同的資源,例如虛擬記憶體和全域變數。
  • 此外,執行緒也有自己的私有數據,例如堆疊和暫存器,在上下文切換時也需要保存。

這樣,執行緒的上下文切換其實可以分成兩種情況:

  • 首先,前後兩個執行緒屬於不同的進程。此時,由於資源不共享,切換過程與進程上下文切換相同。
  • 其次,前後兩個執行緒屬於同一個行程。此時,由於虛擬記憶體是共享的,所以切換時虛擬記憶體的資源保持不變,只需要切換執行緒的私有資料、暫存器等未共享的資料。

顯然,同一個行程內的執行緒切換比切換多個行程消耗的資源少。這也是多執行緒替代多進程的優勢。

中斷上下文切換

#除了前面兩種上下文切換之外,還有另一個場景也輸出 CPU 上下文切換的,那就是中斷

為了快速回應事件,硬體中斷會中斷正常的調度和執行過程,進而呼叫中斷處理程序

中斷其他行程時,需要儲存行程的目前狀態,以便中斷後行程仍能從原始狀態復原。

與行程上下文不同,中斷上下文切換不涉及行程的使用者態。因此,即使中斷進程中斷了處於使用者狀態的進程,也不需要保存和復原進程的虛擬記憶體、全域變數等用戶態資源。

另外,和行程上下文切換一樣,中斷上下文切換也會消耗 CPU。過多的切換次數會消耗大量的 CPU 資源,甚至嚴重降低系統的整體效能。因此,當您發現中斷過多時,您需要注意排查它是否會對您的系統造成嚴重的效能問題。

結論

綜上所述,無論哪種場景導致上下文切換,你都應該知道:

CPU 上下文切換是保證 Linux 系統正常運作的核心功能之一,一般不需要我們特別注意。

但是過多的上下文切換會消耗 CPU 的時間來保存和恢復寄存器、核心堆疊、虛擬記憶體等數據,從而縮短進程的實際運行時間,導致系統整體效能顯著下降。

以上がLinux CPU でのコンテキスト切り替えの調査の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:lxlinux.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!