2 つのスレッド間のコンテキスト切り替えで正確に保存および復元されるもの
- 同じプロセスで
- 2 つのプロセス間
答えは多くのことに依存しているため、これはかなり複雑な質問です。
少なくとも、使用中の汎用レジスタとプログラム カウンタ レジスタを保存する必要があります (最新の CISC/RISC スタイルの汎用 CPU の一般的な設計を前提としています)。
コンテキストの切り替えに関連して最小限の努力だけをしようとすることは、いくつかの学術的関心のトピックであることに注意してください
私の参考文献は少し古くなっているかもしれませんが、Linux は明らかにパブリック ドメインでこれに関するより多くの情報を入手できます。
タスクの状態とタスクのプロセスに関連する多数のフィールドを含む「task_struct」があります。
これらの 1 つが「thread_struct」です</p>
/* このタスクの CPU 固有の状態 */
- struct thread_struct thread;
キャッシュ TLS 記述子、デバッグ レジスタ、
障害情報、浮動小数点、仮想 86 モード、または IO パーミッションに関する情報を保持します。
各アーキテクチャは、スイッチに保存されたレジスタやその他の値を識別する独自の thread_struct を定義します。
これは、(スーパースカラーまたはパイプライン関連のアーキテクチャ設計を介して)複数の実行中の命令を許可する名前変更レジスタの存在によってさらに複雑になります。コンテキスト スイッチの復元フェーズは、CPU のパイプラインが最初の空の状態で復元されることに依存する可能性が高く、パイプラインでまだリタイアされていない命令は効果がないため無視できます。これにより、CPUの設計が非常に難しくなります。
プロセスとスレッドの違いは、プロセス スイッチ (すべてのメイン ストリーム オペレーティング システムでは常にスレッド スイッチを意味します) は、メモリ変換情報、IO 関連情報、およびパーミッション関連構造を更新する必要があることです。
これらは主に、よりリッチなデータ構造へのポインターであるため、スレッド コンテキスト スイッチに関連する大きなコストにはなりません。
コンテキストの切り替えが同じプロセスのスレッド間で行われる場合、現在のスレッドのすべての不揮発性汎用レジスタが保存され、新しいスレッドのレジスタが復元されます。揮発性レジスタは、現在のスレッドの実行が割り込みによって中断された場合にのみ保存する必要があります。スレッドが使用するコプロセッサ (浮動小数点プロセッサなど) のレジスタも保存および復元する必要があります 切り替えが 2 つのプロセスのスレッド間である場合、通常のコンテキスト切り替えに必要なものに加えて、メモリおよび IO 管理関連変更も行う必要があります。たとえば、プロセスに必要なメモリ保護はページ テーブルとページ ディレクトリ テーブルを使用して実現され、各プロセスには一意のページ ディレクトリ テーブル アドレスがあり、プロセスが変更されたときに変更する必要があります。
これは使用している OS によって異なりますが、すべてのレジスタ (命令カウンターを含む) の内容を保存し、切り替え先のスレッドのレジスタをロードする必要があります。
同じプロセス上の 2 つのスレッド間の切り替えに関して私が思いつく唯一の違いは、L1 キャッシュと MMU キャッシュの内容が失われないことです。
よくわかりませんが、正しく覚えていれば、ワーキングメモリセットも切り替えられます。