コンテキストスイッチ
Context Switch
CPUが現在実行中のプロセスやスレッドの状態を保存し、次に実行するプロセスやスレッドの状態を読み込んで処理を切り替えること。
🐾 猫で例えると?
喧嘩から眠りへ切り替わる猫の姿は、状態の切替を覚える目印になります。ただし、寝るだけでは別タスクの再開にはなりません。「どのおもちゃで遊んでいたかを覚えて一旦休み、別の遊びの続きを始める」と考えると、実行位置を保存して他の処理を再開するコンテキストスイッチに対応します。
💻 システム開発における「コンテキストスイッチ」とは?
OSから実行先として見える1つの論理CPUでは、実行するスレッドを切り替えながら複数の仕事を進めます。複数コアや複数の論理CPUがある構成では、複数のスレッドが同時に実行されることもあります。「CPU全体で常に1つしか動かない」という意味ではありません。
切替では、命令の実行位置やレジスタ、スタックポインターなど、再開に必要な状態を保存・復元します。通常、スタック上のデータを切替のたびに丸ごとコピーするわけではありません。異なるプロセスへ切り替える場合には、アドレス空間に関する切替も関係します。
⚠️ コンテキストスイッチの仕組みとオーバーヘッド
コンテキストスイッチはOSのカーネルによって制御されます。割り込み(I/O要求やタイマーなど)やシステムコールがトリガーとなります。しかし、この切り替え作業自体がCPUリソースを消費するため、「コンテキストスイッチのオーバーヘッド」と呼ばれるパフォーマンス低下の要因になります。
コンテキストスイッチの頻度と影響
あまりにも頻繁にコンテキストスイッチが発生すると、CPUはプログラムの実行よりも切り替え作業(状態の保存と読み込み)ばかりに時間を取られてしまい、システム全体の処理能力が著しく低下します。これを防ぐために、OSはスケジューリングアルゴリズムを駆使して、最適なタイミングで切り替えを行います。
// Linuxでのコンテキストスイッチ数の確認(vmstatコマンド)
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 1234567 890123 456789 0 0 1 5 10 50 10 5 85 0 0
2 0 0 1234000 890123 456789 0 0 0 0 100 500 20 10 70 0 0
...
// 'cs'列が1秒間に発生したコンテキストスイッチ数。
// 'in'列は1秒間に発生した割り込み数。 cs は切替頻度を観察する手がかりです。普段の同じ負荷と比較し、CPU時間・応答遅延・実行待ちも合わせて確認します。切替回数が多いだけで異常とは限らず、I/O待ちの多い正常な処理でも増えます。
🛠️ コンテキストスイッチを賢く使うためのポイント
アプリケーション開発やインフラ構築において、不要なコンテキストスイッチを減らすことはパフォーマンスチューニングの鉄則です。
- 適切なスレッド数の設計: CPUコア数に対して過剰なスレッドを生成すると、切り替えによるオーバーヘッドが急増します。
- 待ち方を見直す: 非同期I/Oを使うと、多数の接続ごとに待機スレッドを作る構成を避けられる場合があります。OS全体の切替がゼロになるわけではないため、変更前後の負荷で効果を測ります。
- プロセスの多重度最適化: Webサーバー(ApacheやNginxなど)の同時接続数やプロセス割り当てをハードウェア性能に合わせて調整します。
激しい喧嘩の途中で急に電池が切れたように眠ってしまう猫たちのように、システムも時には無駄なプロセスを眠らせ、効率よくリソースを切り替えることが重要です。システムの動きが重いと感じたときは、タスクの切り替え頻度やプロセス数を見直してみましょう。