🐙

コンピュータ・システム ~ プログラマの視点から~ (1章の続き)

2024/08/17に公開

オペレーティング・システムがハードウェアを管理する

プロセス

プロセスはOSによる抽象化によって提供される概念である。
僕たちが何かプログラムを実行するとき、CPUやメモリ、IOデバイスの占有状況を多くの場合出来にする必要がない。この幻こそがプロセスだ。
プロセスは同一システム内で並行に走らせることができる。大部分のシステムでは、搭載されているCPUの数よりも多くのプロセスを走らせることができる。
現代の多くのコンピュータはマルチコアプロセッサだが、シングルプロセッサのコンピュータでもプロセスを高速に切り替えることで、1つのCPUが複数のプロセスを同時に実行できている幻を見せてくれる。
このメカニズムはOSのコンテキスト・スイッチという仕組みによって実現される。
OSはプロセスが走るために必要なすべての情報をコンテキストとして保持している。
具体的には、レジスタファイルの値やPCの値、メインメモリの内容などがコンテキストには含まれる。
1つのプロセスから違うプロセスに制御を移行する際、現在のプロセスのコンテキストを保存し、新しいプロセスのコンテキストを復元し、制御を新しいプロセスへと移行させる、コンテキスト・スイッチを行う。

具体的にhelloプログラムを走らせた場合について考えてみる。
最初はshellプロセスが走っている。あなたの入力を待っている。入力がなされてEnterが押されたら、シェルは入力の終わりを検知して、helloプログラムへとコンテキストスイッチを行う。helloが終わったら、shellプロセスにコンテキストスイッチを行う。

このようなプロセス間の制御の移動はカーネルによって行われる。
カーネルはOSの一部でメモリに常駐している。カーネルはプロセスじゃない。 システムが全プロセスを管理するために使うコードとデータの集合である。

アプリがOSにファイルのIOのような要求を行う際には、特殊なシステムコール を発行し、カーネルに制御が移行する。

スレッド

スレッドはプロセス内に複数存在するプログラムの実行単位だ。
各スレッドは、そのプロセスのコンテキストで走り、同じコードとデータを共有する。
スレッド間通信は多くの場合で、プロセス間通信よりも効率的である。

仮想メモリ

仮想メモリはメインメモリを独占的に使っている幻をプロセスに見せる技術である。
各プロセスから見ると、メモリは仮想アドレス空間と呼ばれる統一的な構成を持っているのである。
仮想アドレス空間はアドレスの小さい方から以下の順番で並ぶ。各領域についてはすでに知っているので説明しない。

  1. プログラム・データとコード
  2. ヒープ
  3. 共有ライブラリ
  4. スタック
  5. カーネル仮想メモリ

ファイル

ファイルは一連のバイトであり、それ以上でもそれ以下でもない。
ディスク、キーボード、ネットワークなんでもUNIX I/Oと呼ばれる少数のシステムコール群をつかって統一的なインターフェースを通じて読み書きされる。美しいねぇ...

システムはネットワークを使って他のシステムと通信する

現実では、他のシステムと通信することでシステムは真価を発揮する。
だが、ここのシステムからみればネットワークもただのI/Oデバイスにすぎない。
システムはバイト列をメインメモリからネットワークアダプタにコピーして、データはネットワークを流れていく。同様に送られてきたデータをメインメモリに読み込めばreadできる。
Email, FTP, WWWといったアプリケーションはすべてネットワーク越しに情報をread/writeする能力の上に成り立っている。

その他の重要なテーマ

Amdahlの法則

Gene Amdahlはシステムを部分的に高性能化することの効果を数式で示してくれている。
$ T_{new} = \left(1-\alpha\right)T_{old} + \left(\alpha T_{old}\right)/k $
これよりスピードアップの比率Sは
$ S = \frac{\left(1-\alpha\right)+\alpha/k}{1} $
ここからわかるようにシステム全体のパフォーマンスを上げるには、大部分を最適化する必要がある。

並行性と並列性

複数の処理を同時に行うシステムという一般的な概念を並行性、システムをこうそくかするために並行性を利用することを並列性と呼ぶ。
マルチプロセッサのシステムはマルチコアハイパースレッディングの出現に伴って当たり前になった。ハイパースレッディングは、各コアが複数スレッドを実行できるようにする技術で、より効率的にCPUの処理能力を利用できる。
たとえば、データがキャッシュにロードされるまで特定のスレッドが待つ必要があっても、もう一つのスレッドで処理を進めることが可能である。
また、命令レベルの並列性が実現されるプロセッサの登場や、一つの命令で複数演算を行えるSIMD並列性を持つプロセッサも登場している。

まとめ

1章おわり!まとめると理解が進むので今後も続ける!
コンピュータは抽象化の歴史の上になりたってるんだと改めて感じたし、やっぱりIOの統一的なインターフェースとシステムコールは美しい。

Discussion