MIS.W 公式ブログ

早稲田大学公認、情報系創作サークル「早稲田大学経営情報学会」(MIS.W)の公式ブログです!

コンピュータアーキテクチャ概論【カウントダウンカレンダー2016冬12日目】

こんにちは49代Cashewです。

ということで今日はコンピュータのアーキテクチャについて長々と書きたいと思います。

なんでこのネタで書くのかというと僕が最も興味のある分野で最近このことしか考えてないからですね。

コンピュータアーキテクチャと聞いて何を思い浮かべるでしょうか。もしかするとそんなの興味も持ったことないって人が多いのかもしれませんね。

今回はコンピュータアーキテクチャについてざっくり説明したいと思います。

コンピュータアーキテクチャとは

広義のコンピュータアーキテクチャはコンピュータをどう構成するかという意味を持ちます。(この説明トートロジーのような...) しかしながら現在コンピュータアーキテクチャといった場合、一般に命令セットを指します。 命令セットは例えば普通のPCで使われているi386とかamd64と言えば分かる人も居るのではないでしょうか。

命令セットとは

プログラムっていうのはPCの中では2進数で扱われています。そしてこの2進数の並びは何らかの意味を持っているわけですが2進数と意味の対応づけが必要ですね。この対応づけのことを命令セットと言います。

もしこれでも分かりにくかったら画像とか音を保存する時にjpegとかpngとかgifとかmp3とかwavとかってあるのを思い出してください。 これは中身をどんな順番でどんな形式でどういう工夫をして保存をするかということの違いなのですが、プログラムの2進数もこのような決まりがあるのです。それが命令セットです。

メモリ構成法によるアーキテクチャの分類

まず現在の殆どのコンピュータが採用しているノイマン型コンピュータから説明します。

ノイマン型コンピュータ

ノイマン型コンピュータって何っていきなり聞かれてしまうと困ってしまうのですが、堅く言えば「命令とデータを一つのメモリに格納し、プログラムカウンタを用いて逐次的にプログラムを実行するアーキテクチャ」でしょうか。

ハーバードアーキテクチャ

ハーバードアーキテクチャとは命令とデータを格納するメモリを分けたものです。 メモリを共有しないため命令側のメモリが余ってもデータ側で利用できないし、逆もしかりです。これはデメリットですね。 ではどのようなメリットがあるかというと命令とデータの転送が競合しないという点にメリットがあります。 ノイマン型コンピュータではメモリとCPU間のバスがボルトネックとなり遅くなってしまうと書きましたがハーバードアーキテクチャは命令とデータが分離されているためにデータにアクセスしている間にも命令を取得することが出来ます。

CISCRISC

CISC

CISCは旧来から用いられている命令セットの特徴で一つ一つの命令の長さが一定でなく、メモリアクセスを色々な命令から行うことが出来ることが特徴です。

CISCRISCとは違ってメモリの番地を直接指定して演算を行うことが出来るため、人の頭で考えやすいというメリットがあります。 また、命令長が異なっても良いため、よく使われる命令には短いビット数を、あまり使われない命令には長いビット数を当てはめることでプログラム全体の(機械語の)長さを抑えることが出来ます。(エントロピー符号化と似てますね) 機械語の長さを抑えることが出来るということはメモリへのアクセスの回数を減らすことが出来、CPU-メモリ間のバスがボルトネックとなっている現在ではこの点でCISCは有利です。

殆どのPCで使われているIntelの命令セットはCISCに分類されます。

RISC

RISCCISCよりも出来ることを削減し、高速化を目指したものです。CISCは人が書きやすかったのですが構造が複雑となりすぎ更に遅くなってしまいました。また、コンパイラの登場によってアセンブラを直接書く人が少なくなったこともRISCの普及の一端でもあります。

CISCと比べた時の大きな特徴としてはメモリへのアクセスはロード命令とストア命令しか行うことが出来ない点が挙げられます。このようにすることでほとんどの命令はレジスタと演算器を用いるだけというとても単純化された構成にすることが出来、高速化が見込まれます。また、遅いメモリアクセスを減らすことが出来るという点でも高速になっています。

他には各命令の長さが同じになったことで一気に2命令取ってこようとしたときに2番目の命令の開始場所が1番目の命令をちゃんと読み込むまで分からないということがないため構造も速度も改善されます。

スマホのCPUは殆どがARMというアーキテクチャなのですがこれはRISCです。

Flynnの分類

「フリンの分類」と読みます。不倫とは関係ありません。(ここでスベる) フリンの分類はデータの流れと命令の流れに着目した分類です。

SISD (Single Instruction stream Single Data stream)

ごく普通に考えるCPUの場合はこれで、一つのデータに対して命令を一つづつ適用していくものです。 シングルスレッドしか持たないようなプロセッサはこんな感じですね。 (最近はシングルコアのCPUは珍しくなってきましたね...年老いたものです。)

SIMD (Single Instruction stream Multiple Data stream)

GPUなどのプロセッサがこれに当たります。複数のデータに対して同じ命令を適用していきます。 全く異なる操作を一つ一つに対して行うことは基本的には出来ません。 (基本的には出来ないと書きましたが論理的には可能になっていることが多いです。) SIMDと言うとAVXとかMMXとかが思い浮かぶ人もいるでしょうか。 もちろんこれらもSIMDですが、最近はGPUに押され気味ですね。

MISD (Multiple Instruction stream Single Data stream)

こんな処理の仕方は現実的にはないのですが... 一つのデータに何個もの命令を食わせると言ったら良いでしょうか。 これは無視してもいいはずです。

MIMD (Single Instruction stream Multiple Data stream)

複数のデータに対して複数の命令を適用していくスタイルです。こんなのはあるのかって?あるんですね。 マルチコアプロセッサが最も身近な例でしょうか。他にはデータフローマシンが一例として挙げられますがこれは後述します。

じゃあどれがいいの?

4つ、実質的には3つの分類を挙げましたがMIMDが最強に見えますね。では常にMIMDが最高なのでしょうか。 そんなことはありません。何事にもメリットとデメリットはあるものです。 例えば最も基本的なSISDは要らないでしょうか。こんな聞き方をするわけですから必要な訳ですね。どこで要るのかというとSIMDとかMIMDが必要ない場合です。SIMDやMIMDが要らないケースというのは多々あります。例えばおもちゃの中に入っているマイコンを考えてみましょう。ここでSIMDやMIMDを使わなければいけない処理を行うとは考えにくいですね。一方でSIMDやMIMDはより大きな処理をするためにCPUの大きさが大きくなりがちです。大きくなると何が問題かというとお金がかかるんです。おもちゃにわざわざ必要のないスペックを追求してそれが消費者にウケるかというとそんなことはないわけでSISDの安いCPUというのも必要になってくるわけです。 ではSIMDとMIMDだと何でMIMDを使わないかという話ですが、これもチップの面積の話になります。MIMDでは複数の命令をこなさなければならないため、命令を解釈する部分が命令を同時に実行したい分だけ必要になってしまいます。さらに命令も2進数のデータに過ぎませんからメモリから取ってこなければならない訳です。この配線などを考えるととても大きい面積が必要になってしまいます。 従ってコストが重要なものはSISDを使う。汎用プロセッサではMIMDとSIMDの使い分けという選択が最適解だと考えます。

並列化

今までトランジスタは年々小さくなり続け、CPUの中に入れられるトランジスタの数はムーアの法則に従って増加してきました。しかしながらこの微細化も限界wに達し、これからは小さくならないとされています。

今まではIntelが中心となりトランジスタを小さくしてきました。なのでIntelのCPUが常に性能でトップに立ち続けられたわけです。しかしこれが終われば今度こそ本当に限られた面積の中でより速いアーキテクチャを求めて開発が進んでいくのではないかと考えます。(トランジスタが小さいと同じ面積の中でより複雑な回路を入れられるだけでなく、動作も高速になります。)

トランジスタの高速化が終焉するということはたとえば2つの数を足すといった命令といった単純な計算はもう早くならないということでもあります。ではどうするかというと同時に計算できる部分は計算してしまおうということになります。

命令レベルの並列性

ここでもう少し計算を複雑にしてa+b+c+d(ただしa,b,c,dは整数)という計算を考えてみましょう。この計算を単純に行えばa+bをしてから(a+b)+cを行い((a+b)+c)+dの計算を行いますね。しかし(a+b)、(c+d)を同時に行うことが出来ればその後に(a+b)+(c+d)を計算することで高速に計算することが可能になることがわかると思います。複数の命令を同時に行うことをスーパースカラと呼び既に実現されています。また、スーパースカラを効率的に利用できるようにコンパイラによる最適化も行われている必要がありますね。

他にはメモリへのアクセスが遅いと何回も言っていますが、メモリへのアクセスをしている間にどんどん他の命令を行うことができればうれしいですね。このように出来るようになった命令から実行することをアウトオブオーダと呼び、殆どのPC用のCPUで利用可能です。

このように並列に処理することを命令レベルの並列といいます。他にも手法はありますが...調べてください。

命令レベルの並列性はどの程度高速化出来るかというとポラックの法則というものがあり、面積をn倍にしたらnの平方根分だけ早くなるとされています。つまりこれではあまり早くならないという訳です。

マルチコア

ポラックの法則では面積を2倍にしても1.4倍にしかならないわけですが、同じCPUが2個並べば面積2倍で性能2倍ですね。 命令レベルの並列性をやめて性能が悪いけど面積効率のいいプロセッサを何個も並列に並べて実行しようというのがマルチコアです。 大抵の場合、みなさんが使っているPCのCPUは既にマルチコア化されていると思います。

メニーコア

マルチコアはせいぜい10個位のコアが乗ったことを言うのですが、更にコアを増やしていくとメニーコアと呼ばれるようになります。 例えば中国が最新のスパコン(2016年現在)で利用している申威26010は一つのCPUに260個ものコアが載っています。 これでは今までと同じアプローチをしていては使い切れない訳です。 ここはまだまだ最先端なのでどのように変化していくかは分かりません。

ダイナミックリコンフィギャラブルプロセッサ

注:ここから下は僕の妄想が入っている可能性が高いです。あしからず。

僕が注目しているのはこれなんですね。当然研究したい訳ですが....僕の研究室はメニーコアの方の研究ならあるのですがこっちはあまりしていないという感じなので研究できるかどうかはちょっと分からないですね。

ということはさておき、説明をしたいと思います。

まず、組み合わせ回路だけで構成されている回路ってとても速いですし計算もほしい分だけ作れば並列に計算することが出来ます。どうにかしてこのような構成を取れないかと考えるわけです。

ここでハードウェアを何回も書き換えられるものがあります。そうですFPGAです。(って言ってないか...) FPGAは使えないかと考えてみましょう。FPGAの内部構成から語りたいところですがこの記事の公開期限が迫ってきているため割愛させていただきます。 FPGAは1つの信号線レベルでハードウェアを構成できますからもちろん構成できないということはないわけですが、FPGAを使ったことがあればわかるようにFPGAは瞬時に回路を構成するというのはむずかしいわけです。FPGAも用意された構成情報いくつかを瞬時に切り替えることは可能のようですが、構成情報自体が大きいため非効率的です。

ここでFPGAは1ビットごとに回路を変えられたことを思い出しましょう。 C言語で変数を扱うときは大体32bitか64bitですよね。1bitごとに回路を決めていくのは冗長でしかないのです。 ここで作られるのがリコンフィギャラブルプロセッサです。 リコンフィギャラブルプロセッサは何ビットかごとにまとまった回路を自由な配線で繋ぐことができます。

とても速くなりそうだと思いませんか?

おわりに

拙筆をここまで読んで頂きありがとうございます。過去2回の記事も結構だらだらした記事になってしまったのでそうはならないように気をつけたつもりですがやはり長くなってしまいました。

MIS.Wでも色々とありましたが入らなければ他人のままであったであろういい先輩、後輩、友人に出会うことが出来たと思います。

過去記事も見たことなかったら見てね

これはB3が適当に覚えていたことを適当に書いたものです。 また多少の妄想が入っている可能性があります。 正確性は保証いたしかねます。