CPU

現在勉強している基本情報技術者試験についてまとめたものです。
自分のアウトプット用なので見やすさなどは期待しないでください。

# CPUとコンピューターの5大装置
コンピューターは大きく、次の5つの装置で動いている。

- 制御装置(CPU)･･･各装置を制御する。
- 演算装置(CPU)･･･命令に従って演算を行う。
- 出力装置･･･絵や画面などに処理の結果を出力する。
- 入力装置･･･文字や画像など、様々なデータを入力する。
- 記憶装置･･･動作に必要な情報を保存する。主記憶装置と補助記憶装置がある。

**プログラム内蔵方式（プログラム記憶方式）**
コンピューターを動かす為のプログラムは普段は補助記憶装置に置かれているが、CPUが直接やり取りを行うのは主記憶装置の為、実行時にプログラムを予め主記憶装置上に読み込んでおく方式。

**逐次制御方式**
命令を1つずつ取り出し、順番に実行していく方式。

**ノイマン型コンピューター**
プログラム内蔵方式や逐次制御方式のような特徴を持つコンピューターのことで、現在使われているコンピューターのほとんどがこのタイプ。

**主記憶装置のアドレス（番地）**
主記憶装置の一定の区画ごとに割り振られた番号のことで、この番号を指定することで任意の場所に読み書きをすることができる。

# レジスタ
CPUが命令を実行するために取り出した情報を、CPU内部に一時的に記憶する為の装置。
レジスタの種類は下記のようなものがある。

|名前|　　　　　　　　　　　　役割|
|:-:|:--|
|プログラムカウンタ|次に実行するべき命令が入っているアドレスを記憶する。|
|命令レジスタ|取り出した命令を一時的に記憶する。|
|インデックス（指標）レジスタ|アドレス修飾に用いるためのレジスタで、連続したデータの取り出しに使うための増分値を保持する。|
|ベースレジスタ|アドレス修飾に用いるためのレジスタで、プログラムの先頭アドレスを保持する。|
|アキュムレータ|演算の対象となる数や、演算結果を保持する。|
|汎用レジスタ|特に機能を限定していないレジスタで、一時的な値の保持やアキュムレータの代用に使ったりする。|

「命令の実行手順」
1.命令の取り出し（**フェッチ**）
プログラムカウンタの示すアドレスを参照して命令を取り出し、それを命令レジスタに記憶させる。
その後、次の命令に備えてプログラムカウンタの値を1つ増加させる。

2．命令の解読
命令レジスタに取り出した命令は、命令部（実行させたい命令の種類を示すコード番号）とオペランド部（処理対象となるメモリアドレスなど）に分かれており、命令部の中身を命令デコーダへと送る。
命令デコーダは命令部のコードを解読して、必要な装置に制御信号を飛ばす。

3．対象データ（オペランド）読み出し
命令レジスタのオペランド部から、処理の対象となるデータを読み出し汎用レジスタなどに記憶させる。

4．命令実行
汎用レジスタから処理対象のデータを読み出し、処理を実行する。
その後、結果を汎用レジスタに書き戻して終了。

**実行アドレス（有効アドレス）**
計算によって求めた主記憶装置上のアドレス。

**命令語**
コンピューターが理解できるよう0と1で構成された機械語。

**アドレス修飾（アドレス指定）**
何らかの計算によってアドレスを求める方式。

**即値アドレス指定方式**
オペランド部に対象となるデータそのものが入っている方式。
値をそのまま使うため、メモリの参照は行わない。

**直接アドレス指定方式**
オペランド部に記載してあるアドレスが、そのまま実行アドレスとして使える方式。

**関節アドレス指定方式**
オペランド部に記載してあるアドレスの中に、対象となるデータが入っている個所を示すメモリアドレスが記された方式。
オペランド部が示すアドレスの中のデータが実行アドレスとなる。

**インデックス（指標）アドレス指定方式**
オペランド部の値に、インデックス（指標）レジスタの値を加算することで実行アドレスを求める方式。
この時加算するのは、オペランド部のインデックスレジスタ番号が参照するインデックスレジスタ内の値になる。

**ベースアドレス指定方式**
オペランド部の値にベースレジスタの値を加算することで実行アドレスを求める方式。
ベースレジスタはプログラムがメモリ上にロードされた時の先頭アドレスを記憶しているので、そこからの差分をオペランド部で指定することになる。
こうすることでメモリ上のどこにプログラムがロードされても、命令を変えなくて済む。

**相対アドレス指定方式**
オペランド部の値にプログラムカウンタの値を加算することで実行アドレスを求める方式。
プログラムカウンタには次に実行される命令へのメモリアドレスが記憶されているので、メモリ上にロードされたプログラムの命令位置を基準として、そこからの差分をオペランド部でしてすることになる。

前述のベースレジスタは無いが、メモリ上のどこにプログラムがロードされても大丈夫なようにしたい場合に使用する。

# CPUの性能指標
**クロック周波数**
コンピューターに入っている様々な装置を、周期的に合わせて動かす際の1秒間に繰り返される回数で、単位は[Hz]。

**クロックサイクル時間**
クロック周波数/時間で求められる、1クロックに要する時間。

**CPI(Clock cycles Per Instruction)**
1命令当たり何クロックサイクル必要かを表す数値。

例えば、1GHｚのCPUで3CPIの場合、命令実行時間は下記の計算で求めることができる。

$1秒 / 10^9Hz = 10⁻⁹秒 = 1ナノ秒$（クロックサイクル時間）
$1ナノ秒 * 3クロック = 3ナノ秒$（命令実行時間）

**MIPS(Million Instruction Per Second)**
1秒間に実行できる命令の数で、単位は百万単位で表す。

**命令ミックス**
よく使われる命令を1つのセットにしたもので、より正確なMIPSを求める場合これらの命令の所要時間を平均して算出する（**平均命令実行時間**）。

下記のような2つの命令を1GHｚのCPUで処理する場合、MIPSは次にように算出する。

- 命令1･･･実行時間:10クロック,出現頻度:60%
- 命令2･･･実行時間:5クロック,出現頻度:40%

$1秒 / 1GHz = 10⁻⁹秒 = 1ナノ秒$（クロックサイクル時間）
$10クロック * 1ナノ秒 = 10ナノ秒$（命令1の実行時間）
$5クロック * 1ナノ秒 = 5ナノ秒$（命令2の実行時間）
$10ナノ秒 * 0.60 + 5ナノ秒 * 0.40 = 8ナノ秒$（平均命令実行時間）

$1秒 / 8ナノ秒 = 1秒 / (8 * 10⁻⁹)秒$
　　　　　　$= 0.125 * 10^9秒$
　　　　　　$= 125000000$
　　　　　　$= 125MIPS$

# CPUの高速化
逐次制御方式で命令を単純に実行していくと、下記のような無駄が発生してしまう。

||||||||||||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|命令1|取出|解読|読出|実行|||||||||
|命令2|||||取出|解読|読出|実行|||||
|命令3|||||||||取出|解読|読出|実行|

このような無駄を無くす為に様々な手法で効率化を図る。

**パイプライン処理**
複数の命令を並行して実行することで全体の処理効率を高める為の手法。
それぞれの処理が次の処理を待たず別の命令に移るので、所要時間が短くなる。

||||||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|命令1|取出|解読|読出|実行|||
|命令2||取出|解読|読出|実行||
|命令3|||取出|解読|読出|実行|

**分岐予測**
分岐条件が発生した際、次の命令がどれかを予測することで無駄な待ち時間を発生させないようにする。

**投機実行**
分岐予測で予測した命令を、後々無駄になるかもしれないが実行しておく手法。

**スーパーパイプライン**
各ステージの中身をさらに細かいステージに分割することで、パイプライン処理の効率アップを図る。

||||||||||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|命令1|取出1|取出2|解読1|解読2|読出1|読出2|実行1|実行2|||
|命令2||取出1|取出2|解読1|解読2|読出1|読出2|実行1|実行2||
|命令3|||取出1|取出2|解読1|解読2|読出1|読出2|実行1|実行2|

**スーパースカラ**
パイプライン処理を行う回路を複数持たせることで、まったく同時に複数の命令を実行できるようにしたもの。

||||||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|ユニットA|命令1|取出|解読|読出|実行||
|ユニットB|命令2|取出|解読|読出|実行||
|ユニットA|命令3||取出|解読|読出|実行|
|ユニットB|命令4||取出|解読|読出|実行|

**CISC(Complex Instruction Set Computer)**
CPUに高機能な命令を持たせることによって、一つの命令で複雑な処理をする基本設計。
**マイクロプログラム**を内部に記憶させることで高機能な命令を実現できる。

**RISC(Reduced Instruction Set Computer)**
CPU内部に単純な命令しか持たない代わりに、それらをハードウェアのみで実装して、一つ一つの命令を高速に処理する基本設計。
**ワイヤードロジック**によってすべての命令をハードウェア的に実装する。