
本記事は組み込みエンジニア向けのTipsです。
エンベデッドシステムスペシャリスト試験を目指す人を想定読者として、プロセッサの概要についてまとめます。
私自身これからエンベデッドシステムスペシャリストを取得しようとしています。対策本で勉強中ですが、掻い摘んだ記述が多いため系統的な情報にまとめようと思い記事を執筆しています。
掻い摘んで知りたい方は、画像だけ見ても粗方理解できるようにしています。
誤解もあるかもしれませんが、お気づきの先輩エンジニアの皆様はコメントいただけると幸いです。
目次
コンピュータシステムの一般的な構成

パソコンや組込みシステムなどのコンピュータは、主として
- プロセッサ
- 入力装置
- 記憶装置
- 出力装置
により構成されます。
プロセッサ内には、「制御器」と「演算器」が含まれており、制御器が各種装置に指令を送り、データのやり取りを行うことで、複雑な動作を実現しています。
ここで、「入力装置」は、ユーザーの動作や周囲環境の情報を取り込むためのインターフェイスとなる装置です。PC向けでは「マウス」や「キーボード」が一般的です。組み込み向けでは分野により多岐にわたりますが「バーコードリーダ」や各種「センサ」などが挙げられます。
次に、「記憶装置」では、プロセッサの演算結果や各種データを格納するための装置です。プロセッサの作業スペースとなる主記憶装置となる「RAM」や設定ファイルやユーザーデータを保存する補助記憶装置となる「HDD」や「SSD」が一般的です。
最後に、「出力装置」ですがプロセッサの演算結果を「ユーザー」や「周囲環境」に出力するためのインターフェイスとなります。PC向けでは、「ディスプレイ」が該当します。組み込み装置向けでは、こちらも多岐にわたりますが「モータ」や「表示灯」などが挙げられます。
この記事では、プロセッサがどのように動作しているかについて詳しく取り上げていきます。
プロセッサの種類

プロセッサには、「CPU(Central Processing Unit)」、「DSP(Digital Signal Processor)」、「GPU(Graphics Processing Unit)」などがあります。
CPUは最も一般的なプロセッサで一般向けPCにも組み込みボードにも基本的には搭載されており、「制御機能」と「演算機能」を提供しています。MPUと呼ばれることもあります。
一方で、DSPとGPUは特化型の「演算装置」です。
DSPは主に音声・画像・制御などの信号を処理するためのデジタルフィルタの演算を行うために用いられます。というのも、基本的にデジタルフィルタの演算は積和演算と呼ばれる。
A = A + B × C
を何度も何度も行います。この演算を超高速でできるのがDSPです。
一方で、GPUはグラフィックスのレンダリング向けに数千のコアを同時に動かして計算するのが特徴です。数千のコアを同時に動かしてもできる演算というのは、数千の計算式が互いに干渉しない単純な演算であるということです。このような特徴から、近年では大規模な並列演算が必要となるニューラルネットワークなどの処理など、グラフィックス以外の分野でもGPUが使われています。このような使い方をGPGPU(General Perpose GPU)などと呼んでいます。
プロセッサの動作

プロセッサの中身をもう少し見ていきましょう。制御器の中には、「デコーダ」と「フェッチユニット」と呼ばれる要素があります。また演算器の中にはALU(Arithmetic and Logic Unit)と呼ばれる算術演算と論理演算を実現するユニットが含まれています。そして、プロセッサの中には、各種状態を記憶するためのレジスタと呼ばれるメモリがあります。それぞれの役割を見ていきましょう。
主記憶装置などのメモリから命令を読み込むユニット
読み込んだ命令の内容を解釈するユニット
次に読み込む命令のアドレスが記載されたレジスタ
フェッチユニットが読みだした命令を格納するためのレジスタ。その後、デコーダが読みに来る。後述するパイプライン処理やスーパースカラを使うプロセッサの場合、同時並行して動作する命令の数だけ命令レジスタが用意される。
CPUの演算状態や分岐のための状態などがまとめて保持されるレジスタ。その内容はCPUの命令セット毎に異なる。
演算に用いるデータ置き場。昔はレジスタの容量が小さかったためこのような専用のレジスタをおいていたが、近年ではレジスタの大容量化であまり意識されない。
特定の用途を持たずプログラム次第で自由に使えるレジスタ。ここを上手に使うことで高速な演算が実現できる。
処理サイクル

感の良い読者は前述の各要素の説明によりCPUの動作がわかったと思うが、CPUの処理の流れをまとめていく。
CPUは、「フェッチ」「デコード」「実行」「ストア」「ライトバック」の順に処理を行い、これを繰り返すことでプログラムを実行する。
フェッチは、プログラムカウンタから次の命令が記述されたアドレスを参照し、主記憶装置の該当メモリから命令を読み出し、命令レジスタ似格納することである。
デコードは、命令レジスタから命令を読みだし、その処理内容を解釈することである。
実行は、解釈した内容に従い演算を行うことである。
ストアは、演算結果を該当するメモリに書き込むことである
ライトバックは、次の図のようにCPU内のキャッシュメモリから主記憶装置にデータを移す処理のことである。
ライトバック方式とライトスルー方式

というのも、CPU内にはキャッシュメモリと呼ばれるプロセッサとの高速通信が可能なメモリ呂行があり、主記憶装置との間を中継することができる。演算器から直接主記憶装置に書き込もうとすると通信時間が長く時間がかるため、演算器を長く拘束してしまい、処理サイクルが遅くなる。
そこで考え出されたのがライトバック方式と呼ばれる手法である。これは、演算器の結果はキャッシュメモリに書き、キャッシュメモリが溢れたときに主記憶装置に溢れた分を書き写すという処理である。これにより演算器の拘束時間は最小で済む。
一方で、キャッシュメモリと主記憶装置に同時に書き込みを行う方式をライトスルー方式と呼ぶ。
命令セット

次に、先ほどから出てくる、CPUへの命令について見ていく。
CPUへの命令は命令セットと呼ばれ、「オペコード」と「オペランド」の組み合わせにより構成される。
オペコードは命令の種類を表し、例えば加算や減算、分岐などである。
オペランドはその引数にあたり、レジスタやメモリのアドレスや、演算に用いる数そのものである。
オペコードの種類や、その並べ方や命令の長さはCPUの規格毎に異なる。
また、1つの命令後の中に複数の命令を構成し、同時に実行するVLIW(Very Long Instruction Word)という方式もある。Intel CPUのx86などのアーキテクチャでも用いられている。
CISCとRISC

命令セットは、各CPUメーカーの製品毎に異なるが、命令の設計方針により、
CISCとRISCに分けられる。
Complex Instruction Set Computerの略です。1命令で複雑な処理を実現したいという設計思想に基づいて設計された命令セットです。
というのも、昔は主記憶装置の容量が小さかったため、長いプログラムを書くことができませんでした。そのため、1命令あたりでできることを増やす必要が有りました。
そのために、CISCの命令は内部でマイクロコードと呼ばれる単純な処理の組み合わせに分解されて処理されます。これをマイクロプログラム方式と呼びます。
マイクロコードがいくつに分解されるかは当然命令毎に異なるため、処理時間も命令毎に異なります。
Reduced Instruction Set Computerの略です。最低限の処理だけを実現したいという設計思想に基づいて設計された命令セットです。
1命令を単純にし、そして後述するパイプライン処理を有利にすることで性能の向上が見込めるという思想で設計されています。
デコードされた命令はそのまま処理されます。これをワイヤードロジック方式と呼びます。

CISCとRISCの特徴を比較します。結局は大規模なプログラムの実現のために、CPUの回路規模を大きくすることで実現するのがCISC、プログラムサイズを大きくすることで実現するのがRISCという印象です。
処理性能についての優劣は一概につけられません。
パイプライン処理

先程出てきた、パイプライン処理と呼ばれる高速化手法について説明します。先に述べたCPUの命令サイクルを、命令Aのサイクルが終わったら、命令Bのサイクルを実施する・・・としていくと処理をシンプルですが、各ユニットは暇している時間がながなくなります。
そこで、各処理単位で並列に演算していこうというのがパイプライン処理です。
しかし、絵で示したとおり、CISCの場合、命令長や処理時間がことなるため、フェッチや実行の時間がバラバラとなるため、どうしても暇になるユニットが出てしまします。上記の例では3サイクル目ではデコーダが暇になってしまっています。
一方で、RISCでは、各処理の時間が同一になるように設計するため複数の命令を並行して行っていっても、無駄が生じません。実質、1命令1サイクルで行うことが可能になりこの点が有利となります。

さらに、高速化を図るために「スーパパイプライン」という手法があります。これは、単純に、フェッチやデコードなどの処理を分割してそこも平行に処理できるようにすればより高速な処理が実現できるという発送です。
一方で「スーパースカラ」は、パイプライン自体を複数用意し、前後の処理に干渉しない場合のみ、複数のパイプラインを使って並行処理を行う手法です。

ここまで、パイプラインの優れた点をまとめてきましたが、当然弱点もあります。
「データハザード」は、直前の命令の結果を使って次の処理を行う場合に、結果を待つ必要があるという問題です。
「構造ハザード」は、複数の命令スロットが1つしかないCPU資産を同時に使用した際の待ちが発生する問題です。
「制御ハザード」は、分岐命令があると、パイプライン上に残っている構造の命令が破棄する必要がある問題です。
データの並列処理に関して

処理の並行化を見ていきましたが、1命令自体の処理内容を並列化するという観点から、命令は4つに分けられています。
1命令で1データを扱うSISDは、いわゆる普通の演算のイメージで良いです。
1命令で複数データを扱うSIMDは、配列の各要素に同一の演算を同時に実行するようなイメージです。画像処理など大量のデータの塊に同一処理を施したい場合などに高速化のため用いられます。Intel製のCPUなどでこの処理ができる命令セットが用意されていたりします。
次に、複数命令で1データを扱うMISDですが、冗長性が確保できるメリットがあるものの、実施例はあまり有りません。
最後に、複数の命令で複数のデータを扱うMIMDですが、マルチコアCPUの動作がこれに該当します。
まとめ
プロセッサの概論をまとめてきました。
今回取り上げていない要素として、「割り込み」、「IOマップへのアクセス方法」がありますが、こちらは、組み込み分野において実務でも特に意識する大切な内容となるため、次の記事でまとめようと思います。
気力が続く限り続けようと思うので、「ここもっと詳しく」とか「この内容取り上げて!」とか「ここは違うんじゃない」などコメントで反応もらえると嬉しいです!
では、また次回会いましょう!