Posted at

【Linux入門】OSとCPUとメモリの基本概念

新年明けましておめでとうございます。 :sunrise:

普段はRuby/Railsを中心にお仕事をしていますが、今年はもう少しプリミティブなレイヤーの知見も増やしたいなと思っています。

今回はOS、CPU、メモリについてザックリまとめました。


前提


  • Linuxをベースに取り上げています。


OSとは

Operating Systemの略です。

ハードウェアを直接操作し、アプリケーションやミドルウェアの実行に必要な機能を提供します。

つまり、OSがハードウェアとソフトウェアの橋渡しをしてくれます。

このおかげで、ソフトウェア開発者は下記のような恩恵を受けています。


  • プログラムを組む上でハードウェアの詳細な仕様を理解する必要はない


    • OSがそれぞれのハードウェアへのアクセス方法を抽象化して提供してくれている



  • 複数プログラムを実行した際の複雑なプロセス(プログラムの実行単位)管理をする必要はない


    • OSが良しなに管理してくれる



どれもシステムが当たり前にやっていてくれていること過ぎて、これを恩恵とすら感じないかもしれませんね。

OSの役割をザックリ図にまとめると下記のような感じになります。


OSが存在しない場合

Screen Shot 2019-01-01 at 16.01.44.png


OSが存在する場合

Screen Shot 2019-01-01 at 16.08.52.png

上記のように、OSはデバイスに対する処理をまとめたデバイスドライバを介してハードウェアとのやり取りを行います。

そのほか、メモリ管理やプロセス管理などもOSによって管理されます。


カーネル

OSにはいろんな機能や役割を持っていますが、その中核を担っている部分をカーネルと言います。

wiki大先生によると、


カーネルはメモリ、CPU、入出力を中心としたハードウェアを抽象化し、ハードウェアとソフトウェアがやり取りできるようにする。また、ユーザープログラムのための機能として、プロセスの抽象化、プロセス間通信、システムコールなどを提供する。


このカーネルがあるおかげで、我々は上記のようにハードウェアのややこしい仕様や小難しいプロセス管理などをしなくても済むんですね。

ちなみに、カーネルを介して実行するにはプロセスに権限が必要であり、その名前をカーネルモードと言います。

通常のプロセスはユーザーモードと呼ばれます。

プロセス管理やハードウェアへのアクセスなどはシステム上非常に重要な昨日なので、このように特別な権限を持つ場合にのみアクセスできるようになっています。

カーネルの話だけでも膨大な量になるので、詳細は別に記事を作ろうかなと思います。


CPUとは

Central Processing Unitの略で、日本語では中央処理装置と言います。

wiki大先生によると、


CPUは記憶装置上にあるプログラムと呼ばれる命令列を順に読み込んで解釈・実行することで情報の加工を行う。CPUはコンピュータ内での演算を行なう中心であり、CPUは通常はバスと呼ばれる信号線を介して主記憶装置や入出力回路に接続され、何段階かの入出力回路を介して補助記憶装置や表示装置、通信装置などの周辺機器が接続され、データやプログラムなど情報のやりとりを行う。


要は、プログラムが動くのはこのCPUが頑張ってくれているおかげですね。

ここまで色々やってくれていると、人間の脳に例えられることが多いのも頷けますね。


メモリとは

実行中のプログラムやデータなどを一時的に保持する場所のことであり、コンピューターにおける主記憶を担当します。

作業台や机に例えられることが多く、作業台のスペースが大きい(メモリ量が大きい)方が、その上にたくさん書類や筆記用具を広げられるので作業が捗る(性能が良い)です。

プログラムが実行される際、プログラムのデータなどがメモリ上に一時的に情報が保持されます。

→仕事する際に、書類を机に広げます

CPUはプログラムを実行する際にこのメモリからデータの読み書きをすることで、ストレージデバイスにアクセスするのに比べて高速に処理できます。

→机の上だけで仕事ができるので、デスクの引き出しから物を出し入れしなくて済むので作業が快適になります。


メモリ管理

メモリはアドレスと呼ばれる領域で区切られており、それぞれのアドレス内にプロセスやデータが割り当てられます。

Screen Shot 2019-01-01 at 17.49.31.png

ただこのメモリの割り当てを単純に実施すると下記のような困ったことになります。


  • メモリの断片化


    • プロセスをメモリに割り当てたり解放したりしているうちに、空いているメモリの位置がバラバラになる



  • 別用途のメモリにアクセスできてしまう


    • 単純にメモリをアドレスに区切るだけでは、アドレスを指定すればどのプロセスも他のプロセスにアクセスできてしまう



Screen Shot 2019-01-01 at 17.50.45.png

このような問題を解決するために仮想記憶という機能があります。

どするかというと、プロセスが直接システムに搭載されているメモリにアクセスするのではなく、仮想アドレスというアドレスを介して間接的にシステムにアクセスするようにします。

アドレスを仮想化することで都合の良いアドレス構成が可能となり、上記のような問題を解決するのです。

プロセスから見えているアドレスを仮想アドレス、システムに搭載されているメモリの実際のアドレスを物理アドレスと呼びます。

空いているアドレスにデータを入れていくと、MMU(Memory Management Unit)がプログラムの実行に都合の良いように物理アドレスから論理アドレスを作り出してくれます。

この物理アドレスと論理アドレスの対応(マッピング)はページテーブルという名前であり、カーネルが使うメモリ内で管理されています。

Screen Shot 2019-01-01 at 18.23.58.png

また、仮想アドレスはプロセス毎に作られるため(ページテーブルもプロセス毎に作られる)、プロセス毎に仮想アドレスと物理アドレスの対応を管理することになります。

これにより、複数のプロセスがそれぞれ独立した仮想アドレスをもつため、あるプロセスが他のプロセスのアドレスにアクセスすることを防ぎます。

下図のようにメモリ断片化も解消されます。

Screen Shot 2019-01-01 at 18.45.46.png


まとめ


  • OS、CPU、メモリの非常にザックリした仕組みをまとめました。

  • 普段我々がプログラムを組む際には当たり前にスルーしていたことの大半はOSさんがやってくれていた

  • フレームワークやライブラリが氾濫している時代だからこそ、こういったプリミティブなレイヤーの知識も持ち合わせた方がいざという時に役立つかもしれません。


参考