name: cpu class: title, smokescreen, shelf, no-footer # CPU <div class=footnote> <small> (脚注) 後半の「発展:資料編」部分は中間試験に出ません </small> </div> --- class: img-right,compact # CPU動作の概要 <div class=footnote> <small> (脚注) レジスタがある分、電卓より少し賢い動作ができますが、 大雑把にはCPU=超高速な電卓というイメージです (記憶装置などの周辺機器が無いと電卓だけあっても役立たずです) </small> </div> ![height480px](images/compile-process.png) - 演算と制御装置(五大要素) 1. プログラムを**入力装置**から 1. メモリ(**記憶装置**)へ読み込み 1. メモリ上の**機械語**を順次実行 (実行時にはCPU内の小さいが高速な記憶領域(**レジスタ**)を使います) - CPUが解釈できるのは**機械語** - **コンパイル**とは機械語への翻訳 1. ソースコード(例:i=0) -> 1. アセンブリ言語(例:mov $0,ax) -> 1. 機械語(マシン語,例:0xb800) --- class: img-right,compact # 機械語を1対1翻訳したものがアセンブリ言語 ![height320px](/images/os/computer_punchcard_scientist.png) <div class=footnote> <small> (脚注1) 授業では、これ以上の詳細は割愛しますが、 基本情報処理試験の範囲は意外と広く、 レジスタやアセンブリ言語も、もう少し細かいところまで求められます。 例: アドレス指定の直接,間接,相対(アドレス指定) ... C言語のポインタのポインタといったポインタまわりの機械語表現のようなもの (脚注2) 基本情報の午後の部では簡易化したアセンブリ言語でも受験できます。 実はアセンブリ言語を選択するのが(難しい文法がないし)一番簡単といううわさ有り </small> </div> - 機械語は数字(前頁参照)ですが、人間が機械語を直接読み書きするのは辛すぎるので、 アセンブリ言語という**機械語を1対1翻訳した**言語で表現します - 昔の映画のように紙テープを読む(右図)=機械語を生読みなんてしません --- class: compact # 例: アセンブリ言語 ``` 例: siレジスタへaxレジスタの値をコピーする 機械語 <-> アセンブリ言語 // 解説 (機械語より、だいぶ読みやすいよね?) 89c6 mov %ax,%si // movが命令部、%ax,%siがオペランド部 // これはAT&T記法、Intel記法(この例はmov si,axになる)もあります // 授業で使っているGCC(GNU Compiler Collection)はAT&T記法 [むりにC言語っぽい記述をすれば] register ax, si; register_copy(ax, si); ``` - a.outを生で読むと 89c6 のような数字がずらっと並んでいます - アセンブリ言語は1対1翻訳したものです。CPUの一命令が一行で出力されています - 89がmov命令(moveのはずですが、実際の動作はコピー) - c6の部分がaxレジスタとsiレジスタ - あわせると`mov %ax,%si`(movが関数名、引数が%axと%siと思えばよい;スペース区切り) - 参照:レジスタの例とアセンブリ言語でループを解説する例が[付録](#register-details)にあります --- class: col-2,compact # クロック周波数とコア数 - **クロック周波数** - 電圧の上がり下がりが処理の基本単位になっていて、 各部品間のタイミング合わせをしています - CPU内部の周波数が**内部クロック**、 CPU外部(いわゆるバス)は**外部クロック**で内部より数倍おそい - **内部クロックをあげる=高速化**につながりますが、 2000年代後半以降は**コア数**を増やして性能を向上させています - 後述するパイプラインやRISCの工夫でも速くなりますが、 やはりクロック数=1秒間に実行できる命令数が増えれば、 そのぶん速くなるのは自明 - **クロック数による高速化は3GHz付近で限界点に達した** (2000年代前半のIntel Netburstアーキテクチャ,Pentium Dなど) - クロック数を上げることはできても、3GHzあたりを越えると、 使うエネルギー(電力)=発熱のわりに高速化しなくなってきた - このあとの世代、いわゆる**Intel Coreアーキテクチャ**では、CPU単体のクロック数は3GHz付近までで、 プロセッサ(手のひらサイズのLSI)にCPU複数個分をいれるようになりました - この個数を**コア数**と呼びます - 個人向けなら2ないし4個あたりが多く、サーバ用なら64個の製品あり --- class: col-2,compact # CPUの高速化技術 <div class=footnote> <small> (脚注1) CISCはCompilicated Instruction Set Computer、RISCはReduced Instruction Set Computer の略 (脚注2) さらにステージを細かく分けるスーパーパイプラインや、 パイプラインを複数もつスーパースカラという技術も使われています (<-基本情報の範囲) </small> </div class=footnote> - 逐次制御 ... 機械語を順番に実行します - **パイプライン** ... 機械語の命令を平行して実行する。 命令の内容によっては必ずしも逐次実行する必要が無いので、 うまくいけば並列処理をしているかのように速くなる ![height120px](images/cpu-pipeline.png) <wbr> - **CISC** = **多種の命令語**があるCPUの設計 - **RISC** = **命令語が少なめ(厳選)の設計** - 集積密度があがり複雑化する一方のCPUの設計が楽になるし、 単純な命令群のほうがパイプラインに適する - 最適化はコンパイラが頑張る --- class: col-2,compact # GPU - GPU - 画像処理に特化した浮動小数点演算を並列実行できるプロセッサ (いまどきのGPUボード上位機種なら並列実行できる演算器を数千個搭載) - GPGPU (Generic Purpose GPU) - 画像処理以外の分野に流用すること - 機械学習 - 暗号解読 - データマイニング <wbr> - [応用]スーパーコンピュータ - 科学技術計算は浮動小数点演算なので、 GPUボードを束ねればスーパーコンピュータになります。 コストパフォーマンスがよいスパコンが作れます - 電力効率の高い(**省電力**)スパコン - 例: 東工大のTSUBAMEはNVIDIA GPUを大量に並べたスパコンで、 GREEN500(速度/電力の勝負,2013)でTOP (TSUBAMEは「みんなのスパコン」で、 [東工大](https://www.titech.ac.jp/)の人は誰でも使えるらしい、いいな〜) --- name: register-details class: title, smokescreen, shelf, no-footer # 資料: 発展編<br>レジスタとアセンブリ言語の具体例 <div class=footnote> <small> (脚注) 中間試験には出ません </small> </div> --- class: compact # レジスタ: PDP11 (16bit CPU) | |レジスタ | 主用途 | 備考| | ---- | ---- | ---- | ---- | |汎用レジスタ| | | | ||r0 | 汎用 | | ||r1 | 汎用 | | ||r2 | 汎用 | | ||r3 | 汎用 | | ||r4 | 汎用 | | ||r5 | 環境ポインタ | Unixの慣例では環境ポインタ | ||r6 | スタックポインタ | spとも表記される | ||r7 | インストラクションポインタ | ipとも表記される | |メモリ管理レジスタ | SR0,SR1,SR2,SR3 | | SR1,SR3は機種依存 | |管理レジスタ|PSW | ステータスなど|PSW = Processor Status Word| --- class: compact # レジスタ: Intel 8086 (16bit CPU)その1 ||レジスタ | 主用途 | 備考 | ---- | ---- | ---- | ---- | |汎用レジスタ | | | | ||AX | 計算用 | | ||BX | ポインタ | | ||CX | カウント | | ||DX | 一時記憶 | | ||SI | 転送元 | | ||DI | 転送先 | | ||BP | ベースポインタ | | ||SP | スタックポインタ | | ||IP | インストラクションポインタ | | |flags | ステータスなど | | | --- class: compact # レジスタ: Intel 8086 (16bit CPU)その2 ||レジスタ | 主用途 | 備考 | ---- | ---- | ---- | ---- | |セグメンテーションレジスタ | | | ||CS | コード | ||DS | データ | ||ES | エキストラ | ||SS | スタック | - Intel CPUは、もともとセグメンテーションという方式を使っていたため、 アドレス(ポインタ)はセグメントとセグメント内の位置(オフセット)をセットで指定します ``` セグメントアドレス:オフセットアドレス 30A4:0100 -> 30A40 + 0100 = 30B40 が実際のアドレス ``` - この方式は、 低機能なCPU上で低コスト (一度セグメントを決めればオフセットだけで処理可能=アドレス用のメモリも小さくてOK) に大きなメモリを扱うには便利だったようです。 Intelって元々単なるメモリ屋さんだったからPCという思想に興味なし? --- class: compact # Intel CPUでループ(C言語) ``` #include <stdio.h> int main (int argc, char **argv) { int i, sum; sum = 0; for (i = 0; i < 10; i++) { sum += i; } printf("sum = %d\n", sum); } ``` - 単純な足し算をするループです。コンパイルするとCPUが理解できる**機械語**になります - 次頁では、 このループ本体部分の機械語を**アセンブリ言語に逆変換**(disassemble)したものと、 その各行の解説をしています( CPUはIntelです。 本当は64bit環境なので少し違うのですが、 前頁にあわせて、アセンブリ言語と解説は16bit風になっています) --- name: disassembled-loop class: compact # Intel CPUでループ(main部分のアセンブリ言語) ``` objdumpしてmain部分を抜粋(+最初の数行と最後の2行を省略して一頁に)したもの 注: -0x8(%bp)は省略記法,C言語風に書けば「bpポインタに対して *(bp-8) 」相当;mov命令はmoveですが実質コピーです 機械語 アセンブリ言語 解説 c7 45 f8 00 00 00 00 mov $0x0,-0x8(%bp) -0x8(%bp)を0に初期化(変数sumとして利用) c7 45 fc 00 00 00 00 mov $0x0,-0x4(%bp) -0x4(%bp)を0に初期化(変数iとして利用) eb 0a jmp 4行後のアドレス forループの条件部分へジャンプ(4行先のcmp行) 8b 45 fc mov -0x4(%bp),%ax axレジスタに変数iを代入 01 45 f8 add %ax,-0x8(%bp) axレジスタの値を変数sumに加算(sum+=i相当) 83 45 fc 01 add $0x1,-0x4(%bp) 変数iに1を加算(i++相当) 83 7d fc 09 cmp $0x9,-0x4(%bp) 比較 i<=9 をし、結果をフラグレジスタに保存 7e f0 jle 4行前のアドレス フラグレジスタを見て結果がtrueなら4行前へ戻る(ループ) 8b 45 f8 mov -0x8(%bp),%ax 変数sumの値をaxレジスタへコピー 89 c6 mov %ax,%si siレジスタにaxレジスタの値をコピー(変数sum) bf ce 09 40 00 mov $0x4009ce,%di diレジスタにformat文の文字列アドレスをコピー b8 00 00 00 00 mov $0x0,%ax axレジスタを0に設定 e8 a3 fb ff ff call printfのアドレス printf関数(引数はdi,siに設定済)を呼び出す b8 00 00 00 00 mov $0x0,%ax axレジスタを0に設定(関数の返り値の設定) ```