コンピュータアーキテクチャ
基礎概念のメモ的な
普通にタイプミスや解釈ミスがあるかもしれないです
東大 坂井・入江研究室
What Every Programmer Should Know About Memory
コンピュータアーキテクチャ入門
ディジタルな表現
文字コード
1バイトで表現: ASCII, JIS X
2バイトで表現: JIS, シフトJIS, EUC
マルチバイトで表現: Unicode
0と1を電圧の高低で表す、ただし磁気ディスクは磁気のn,sで表すことも。
負の補数表現では絶対値で1つ大きい数まで表せる。
1ビットのスライドの右が全加算器、これをつなげればnビット加算器、全ビット加算器の奇数個を考えるところは排他的論理和を描いても良い。
Nビット加算器は桁数に比例する時間がかかるのであまり使われない。
代わりにキャリルックアヘッドの考え方が使われている。キャリルックアヘッドではlog(桁数)の時間で済む。空間計算量を増やして時間計算量を減らしている。
記憶装置について
Cdは穴の大小で保存している。コンデンサーでは電気が溜まっているかどうかで記憶する。
フリップフロップという記憶装置もある。dフリップフロップとjkフリップフロップがある。
レジスタはnビット記憶装置である。nビットのフリップフロップである。三角は横から1が入ると通るドライバ。3状態ドライバ、1か0か抵抗無限大になるか。
計算のサイクルはレジスタ→ALU(算術論理演算ユニット)→レジスタのサイクルが基本。コンピュータはこれを行なっている。
If文とかforループはまた別のことである。
データの流れと制御の流れ
レジスタとALUだけで大量のデータが扱えるか?
制御信号はどうやって作られるのか?
条件分岐はどうやって実現するのか?
主記憶装置
主記憶装置を含む演算のサイクル
⑴主記憶装置からレジスタに
⑵レジスタ→ALU→レジスタ
⑶レジスタから主記憶装置にデータを移動
メモリの構成
リードとライト
メモリの分類
ROMとRAM
命令
コンピュータの動作を指定するもの
データとして表現される
構成
・操作コード
・レジスタ番地
・メモリ番地
・実行細則
格納
メモリに入れられる、読み出して使われる
フェッチ→デコード→実行→格納の流れ
シーケンサ
次のどの命令を実行するのかを決める機構、命令アドレス生成回路
⑴算術論理演算命令やメモリ操作命令の次:命令メモリの次の番地
⑵無条件分岐命令:ジャンプ先の番地命令
⑶条件分岐命令:判定がYESなら分岐先の命令番地、Noなら+1
命令セットアーキテクチャ
命令は計算機を制御する源となるもので、2進数のデータとして表現され、メモリに格納される
命令は、算術論理演算命令、メモリ操作命令、分岐命令に分類される。
命令実行サイクルは、フェッチ、デコード、実行、結果の格納の4つのフェーズ。
シーケンサとは次の命令アドレスを決める機構で、プログラムカウンタと付加回路からなる。
命令 = 操作op + 対象
対象(オペランド)となるものはデータレジスタ、メモリ語、プログラムカウンタ、レジスタ、即値
Op:log2(対象とするコンピュータの命令セットの大きさ)
Rs, rt, rd:log2(レジスタファイルに含まれるレジスタの数)
Aux, imm/dpl,addr:(命令長) - (他のフィールドのビット数の総和)
命令の表現形式
⑴R型
Op,rs,rt,rd,aux
⑵I型
Op,rs,rt,imm/dpl
⑶A型
Op,addr
アセンブリ言語
機械語は読みにくいので英語の近い記号で表記されていて機械語で一対一対応しているアセンブリ言語を用いる
Add r2 r3 r1 0など
シフト命令
論理シフト(符号を特別扱いしない)sll,srl
算術シフト(符号を保護する)sla,sra
回転シフト(ビット単位で回転)rotatel, ratater
データ移動命令
メモリ→レジスタ間 LOAD命令
レジスタ→メモリ間 Store命令
メモリ→メモリ間 Move命令
分岐命令2:条件分岐命令
Bet rs rt dplなら、rs=rtならpc = (pc) + 4 +dpl(32ビットの時、次の命令は4ビット先である)
アドレシング
アドレスを特定するようなもの
即値アドレシング:定数をアドレシングする(アドレシングぽくない)
ベース相対アドレシング:(rs) + dplでアドレシングする
レジスタアドレシング:そのままレジスタの値を代入
PC相対アドレシング:
バイトアドレシングとエンディアン
バイトアドレシング:アドレシングの単位を「語」ではなく、「バイト」とするアドレシング
エンディアン:語の中のバイトの配列順を定めたもの
エンディアン
リトルエンディあん:大きなアドレスに大きなバイトを入れる
ビッグエンディあん:小さなアドレスに大きなバイトを入れる
サブルーチン
⑴レジスタ値の待避
⑵戻り番地の待避
⑶サブルーチンの先頭番地へのジャンプ
⑷サブルーチン本体の実行
⑸戻り番地へのジャンプ
⑹レジスタ値の復帰
⑺元の命令列の実行再開
RISC
プロセッサの分類
命令数少ない、一語固定長、ここの命令動作単純、レジスタ数多い
CISC
命令数多い、命令形式可変長、ここの命令動作複雑、レジスタ数少ない
CISCが先新田が、実際の計算ではほとんどが単純な命令なので、コンパイルが難しい複雑な命令を扱うので、RISCへと変化していった。
パイプライン処理
今のpcは一秒間に数GHzのクロックで動いている。
パイプライン処理とは全体の作業の工程を分割して、並列に処理することで単位時間あたりの処理量を向上させる流れ作業のことである。
これからの図は、フェッチ、デコード、実行、格納を横に書く。
FD,DE,EWレジスタで1クロックの間はデータや信号を保持して、次のクロックで次のパイプラインに切り替える、という処理を取る必要がある。これらをパイプラインレジスタという。これがあるとFDEWが各クロックで重なり合うように実行することができ、単純に速度が1/4になる。
オーバーヘッド:本来の処理では存在しなかった余計な時間のこと
最も時間のかかるステージの処理時間で全体のスルーが決まる(律速ステージ)
デコードは多少ばらつき、実行はかなりばらつく、
処理時間が長いステージを分割してパイプラインにすることもある
だが、ステージを切りすぎてもだめ、というのもパイプラインレジスタによる遅延が発生するので。
ハザード:クロックごとにパイプライン動作させられない状態のこと
構造ハザード、データハザード、制御ハザードがある。
構造ハザードとは、コンピュータの内部構成が原因のハザードのことで、あるステージを実行中の命令Aと別のステージを実行中の命令Bが同じハードウェア資源を使わなければならない場合などに生じる
データハザードとは、データ依存が解消しないことによるハザードである
データハザードは、依存関係のある命令が離れると緩和される
制御ハザード
制御命令とそれ以降の命令の依存を制御依存といい、制御依存によるハザードを制御ハザードという。
コンピュータはWriteBackされるまで分岐命令かどうかがわからないので、それまでにfetchされたプログラムはストールする。このハザードは避けられない。
パイプライン処理はコンピュータの処理時間に直接関わるもので、多くの人が早くしようと努力してきた。
構造ハザードを解決するにはハードウェア的な物量で解決する!
10個ぐらいのパイプラインのデータハザードはさすがにきついが、そこそこのデータハザードは、フォワーディングという方法で解決することができる。フォワーディングとは、Eステージの結果を、Wステージを経ることなく直接に後続の命令のEステージに送り込むことである。
制御ハザードの解決方法としては、命令アドレス生成を早める、遅延分岐、分岐予測が考えられる。
命令アドレス生成を早めるとは、Eステージではなく、Dステージで次の命令アドレスを確定させることである。
遅延分岐とは、分岐のあるなしにかかわりなく実行する命令を分岐命令の次のアドレスをに入れておき、遅延分岐命令は、定められた数の胸中命令をパイプライン実行した後でPCをセットすることである。
分岐予測とは、分岐が起こるかどうかを予測して処理を進め、予測が外れた場合に分岐命令以下の命令を破棄することである。
最近では、分岐予測の予測をdeeplearningで予測する。というのも、制御ハザードはストールしたら影響がでかい。
また、命令スケジューリングという手法もあり、依存関係のある命令をプログラムの中でできるだけ話した位置に置く、制御ハザードの防止のために遅延分岐を使って遅延スロットに共通命令を充填するなどの方法がある。
キャッシュ
命令メモリ、データメモリはcpuチップの外に置かれるのでアクセスに時間がかかる
メモリの理想:無限大の容量、無限小のアクセス時間、単純なアドレシング
しかしメモリは大容量と高速アクセスは両立できない
今、cpuの命令実行速度とメモリのアクセス時間のギャップが増大している
というのも、cpuは小さくなっているので、電気線が短くなり、そのぶん通信が早くなる
最近はクロックのポジティブエッジとネガティブエッジの両方で動かすようになってきている
これらの問題を解決するために、記憶階層という概念を用いる
1クロックでアクセスできるような大きさの高速小容量のメモリによく使う命令などをあらかじめ入れておく
これらの命令などは空間局所性と時間局所性を用いて、これらの部分を入れておく
空間的局所性:あるメモリ語が参照されたときに、その後の近くの語が引き続き参照される性質
時間的局所性:あるメモリ語が参照されたとき、その後が時間をおかずに再び参照される性質
メモリアクセスの基本パターン
ループ構造、再帰構造、例外処理、データアクセス、マトリクス、リスト、スタック、ローカル変数など
記憶階層を陽に見せる方式
・アセンブリ言語のプログラマが記憶階層を意識しなくてはならない
・命令セットが同じでもメモリの階層構成が変化したりしたらプログラマを作り直さなきゃいけない
ーーー超天才プログラマーがいたら、記憶階層を全て操作できるのでベストなプログラムを書くことができる
記憶階層を見せない方式
見かけ上は、高速で大容量のメモリが1つだけあるものとして機械語のプログラムを書き、ハードウェアの機構でどの階層のメモリをどう使って局所性を生かすかを決める。
この性質を透過性と呼ぶ。
キャッシュ
キャッシュとは記憶階層の最上位のメモリである、1クロックで読み書きをする
キャッシュの読み書きの単位をキャッシュラインと呼ぶ
メモリ書き込み方式による分類
・ライトスルー
・ライトバック
連想度による分類
・ダイレクトマップ
・フルアソシアティぶ
・セットアソンシアティブ
ライトスルー方式は、キャッシュに書き込むと同時にメモリにアクセスするので、時間がかかりそうに見えるが、実はメモリ側にライトバッファという小規模なメモリを設けてそれに書き込むのでそんなに遅くない
キャッシュは、プログラムの常識に従っているので、いろんなメモリ番地に飛びまくるプログラムは遅くなっちゃう(あんまないけど)
ダイレクトマップは一番単純な作り方で、1つのインデックスに対して1つのキャッシュラインを設ける。
同じインデックスで違うタグのものを入れようとするとキャッシュの衝突が起こるが、これはあまり起こらない(確率的にも局所性的にも)
フルアソシアてぃぶ型キャッシュはダイレクトマップとは真逆のもので、ヒット率は異常だが、比較器の遅延がやばい。
これらの中間的なものを考えたのがセットアソシアティブ型である。
キャッシュラインを入れる場所を数カ所用意する(4とかぐらい)
というのも、インデックスが同じでタグが違うものなんかいっきに複数来ないので、4個でもあまり問題は起こらない。
キャッシュミス
1、初期参照ミス:キャッシュラインんを最初にアクセうするときに起こるミス
2、競合性ミス:同じインデクスを持つ異なるキャッシュラインにアクセすることで起こるミス
3、容量性ミス:キャッシュしたいライン数がキャッシュ容量を上回ることで起こるミス
キャッシュラインの交換
・ランダム
・LRU(least recent used)使われていない時間が最も長いラインを追い出しの対象とする
LRUは6bitでどれがLRUであるかをメモっている。
データキャッシュと命令キャッシュはデータハザードを避けるために違うものにする
命令キャッシュの方がミスしちゃダメ
キャッシュが複数レベルのものも存在する
仮想記憶
仮想記憶とは
仮想記憶は主記憶以下の階層化
主記憶と二次記憶のメモリ階層を巨大な主記憶として使えるように透過性をもたせたもの
・主記憶よりも大きな容量のメモリがあるものとしてプログラムが書けるようになる
・また複数のプログラムが1つの物理記憶を安全に分かち合って使えるようになる
動作原理
・アドレス変換:仮想アドレス→物理アドレス
・スワップ:二次記憶のデータ←→主記憶のデータ
仮想記憶の構成
ページ:データ移動の単位
アドレス変換:ページテーブル
スワップ:フルアソシアてぃぶ、ライトバック
ページフォールト
ページが主記憶に入っていない状態
けっこう起こる。OSの例外処理が起こり、中で勝手に処理してるので意識しなくて良い。
1、OSがCPUの処理を中断する
2、テーブルのエントリに入っている二次記憶上のアドレスから主記憶の相手いる場所にページをコピー
3、ページテーブルのエントリに物理ページアドレスを書き込み、有効ビットを1にする
ただ、ページフォールトが起こった時に毎回例外処理をしていたらその処理の時間が長すぎてコンピュータが重くなるのでページテーブルのキャッシュを考える
TLB(translation look aside buffer)
ページテーブルのキャッシュ
フルアソシアティブ方式、というのもこの場所は律速段階になりそうなのでハードウェアを頑張る、コンピュータの性能はこういう律速段階をどのくらい早くできるかどうかで決まる
命令とデータとは別々にTLBが存在する
TLBミスは馬鹿でかいプログラムを動かしている時に起こる可能性があり(天気予報)、普通は考えなくて良い。
天気予報レベルのプログラムになると、TLBミスを起こさない(キャッシュをあふれさせない、ページフォールトを起こさない)ようなプログラムを起こさないことを意識する。これは透過性の原理に反するが、プロになるためにはこのようなプログラムが書けるようになることが必要である。
キャッシュと仮想記憶
・直列型物理アドレスキャッシュ
・並列型物理アドレスキャッシュ
・仮想アドレスキャッシュ
-Aliasingが起きる、というのも仮想アドレスは違くても物理アドレスは同じということがありえる。
メモリアクセス機構
OSが扱うのは物理アドレスである。
逆に、OS以外のユーザプログラムがREAD/WRITEするのは例外なく仮想アドレスである。
ページフォールト、TLBミス、キャッシュミスの3つのエラーが起こる可能性がある。
透過性と互換性
・透過性
-機械語プログラムが実装の詳細に影響されない性質
-キャッシュ、仮想記憶、スーパスからなどの導入で保持される
・互換性
-異なるコンピュータ間で同じ機械語プログラムが同じ動作をする性質
-コンピュータの世代間や上位・下位機種の間で保持されるのが望ましい
基本cpuの設計
アセンブラ:アセンブリ言語のプログラムを機械語(0と1)に変換するプログラム
ハードウェア記述言語は、「+」と打った瞬間にハードウェアが追加される。つまり、モジュールを1つ追加した段階でそのぶんのハードウェアが作られてしまう。
ハードウェア記述言語は、プログラム言語と同様に使用できると言っても、記述するたびにハードウェアが追加されていくので、スタックの上に変数を追加して、仮想的に計算するプログラム言語と訳が違う。
モジュールはタイプに過ぎないので、モジュールに名前をつけてインスタンスとして用いる
CPU設計
パイプライン処理をやりたいので、それぞれの段階をモジュールとして設計する。
動作を基本とし、上位モジュールは①命令フェッチ②命令でコード③実行④結果の格納、をそれぞれモジュールとして設計する。下位モジュールはハードウェアの実態に近いものとする。
最初から全部考えようとすると普通はかけない。ボトムアップな設計では小さいモジュールをたくさん作ってそれを組み合わせていく。
トップダウンな設計では、なんとなくモジュールを作って、そこから1つ1つのモジュールを考えていく。何が必要になっていくのかを書きながら追加していくのが普通である
命令フェッチ部
プログラムカウンタを読み込んで、その番地の命令をインスタンスに入れるだけの簡単なもの
デコード部
パイプライン処理でもやらない限りあまり関係ないので実行部で一緒に処理する
実行部
ややこしい。
何をやっているかというと、fucntionを使って、
命令上位6ビットをオペコード、シフトの時のビットをshift、r型だった時の下から5ビットをoperation、{{16{ins15}}}は符号拡張である、ins15を16回繰り返す。 alu_resultはもとまったresultをaluにぶち込むということ。opr_genはaluに送る制御信号を確定させる。
書き戻し部
クロックかリセットがきたときに動く。
リセットが来たらプログラムカウンタを0番地戻す。
クロックが来たらプログラムカウンタの値を1進める。
これだけの簡単なモジュール。
Nextpcは分岐などで変わるので、値は実行部で決まる。
Npcは分岐か分岐しないかを決定する。
Wregはどのレジスタに書き込むかを決定する。書き込まないときは0を指定する。
データメモリは8ビット幅で、これを4つ使ってメモリの読み書きをする。
Wrengenはメモリのどのバイトに書き込むかを制御する関数である。0が書き込みを表している。
レジスタファイルは単純で、waはライトアドレス、wrenは書き込み信号、ra、rrはリードのアドレスとレジスタ。
これらの4つのモジュールを乗せたらcomputerのトップモジュールの設計は同じです。
命令レベル並列処理
命令レベル並列処理は一緒にいくつもの命令を実行すること
命令レベル並列処理に必要な事項
・ハードウェア資源の投入
-命令キャッシュのバス幅、パイプラインレジスタ、デコーダ、演算フラグなどが並列どPに比例して大きくなる
・レジスタファイルのポート数
-読み出し用のポート数が2P、書き込み用のポート数がP、合計3Pのポートが必要になる
・フォワーディング機構
-前後の命令の間のデータハザードの解消のためには演算ユニットのそれぞれに出力のデータが全ての演算ユニットの入力にフォワードされなければならない。フォワードのデータ線に加えてマルチプレ草のためにp*p=p**2に比例するハードウェアが必要となる。さらに遅延も大きなものとなる危険がある。
・並列実行の制御
-同時実行する命令間の依存関係がないことを保証する必要がある。並列実行される命令間のデータハザードはフォワーディングによっては解消されない。
VLIW
・VLIW = Very Large Instruction World
-1命令の中に複数の演算を入れたアーキテクチャ
-同一命令語中のハザードは全てコンパイラが性的に解決して命令語の中の演算は全て同時に実行する
・VLIWの利点
-プロセッサの制御ロジックが簡単
・VLIWの問題点
-透過性・互換性がない
-静的な並列化の限界
-十分に並列化できない場合の命令フィールドの無駄
スーパスカラ
今はほとんどこれが使われてる
・スーパスカラ-逐次型プログラムを並列十個するアーキテクチャ
・利点-透過性・互換性が維持される
・問題点-ハードウェアが複雑化(ハザード検出のためのハードウェア)
スーパスカラプロセッサの動作
1.命令フェッチ
2.命令プリデコード
フェッチした命令と処理待ちの命令のすべての依存関係を調べ、もし依存関係があれば処理を遅らせる。依存関係のない1つないし複数の命令を実行命令レジスタに入れる。
3.命令ポストでコード
4.演算実行
ポストデコーダで指定された演算群を同時実行する。
5.結果の格納
並列処理ハザード
1.構造ハザード
-並列処理ではユニット数やポート数が足りないための構造ハザードが起こる。これを解決する工夫はいっぱいある!
-例えば、データキャッシュが一度に一つしかアクセス要求を受け付けないとき、ロード・ストア命令を同時に2つ以上実行することはできない
2.データハザード
これがあるから並列度はせいぜい2ぐらいしか出ない
-並列処理する2つの命令の間にはデータ依存関係があってはならない
-プリでコードのステージでデータ依存関係を発見したら、
3.制御ハザード
-フェッチした命令のどちらかが分岐命令の場合、制御ハザードが起こる可能性がある
-並列処理をする場合、ストールの影響は大きくなる。遅延分岐はたくさんの共通命令を必要とすることになるし、分岐予測が外れた場合のペナルティが大きい。
分岐予測コンテストなどが開かれる。最近はディープラーニングが用いられる。
研究者と競技者は違う。競技者は与えられた条件で最高のパフォを、研究者は新しいことを発見する。
Deeper lecture
プログラマは並列性を意識するべきか?
基本的にはNO(スーパスカラも)
ただしマルチコアプロセッサになると意識しなければマルチコアプログラムは書けない
スーパコンピュータもハードウェアの詳細に立ち入ることが多い。
そもそもプログラムはどのように書くべきか?
ループ内部の並列処理→ループアンローリング
宣言的・関数的プログラミング
Declarative program
-問題の解き方を記述するのではなく、問題そのものの仕様を記述する(Wave Front問題)
Wave Frontを並列に実行できる!すごい!
命令レベル並列処理2
静的最適化
・機械語プログラムと命令間依存性
・ループアンローリンぐ
・ソフトウェアパイプライニング
・トレーススケジューリング
静的最適化 = 機械語プログラムの最適化
ハザードを減らすための静的最適化
1、依存関係を解消したり減らしたりする
2、依存関係のある命令同士をプログラムの中で離れた位置に置く
ループアンローリング
小さなループを何周かまとめて一つのループとすることで、分岐命令によるハザードをなくす手法
例えば、配列要素に定数を加えるプログラムだとLOAD命令やADD命令をまとめれば良い
ソフトウェアパイプライニング
ループ間にまたがって命令を移動して依存関係のある命令同士の距離を離すことでハザードを起こりにくくして並列度を上げる
ソフトウェアパイプライニングとループアンローリンぐは組み合わせて用いることができる
トレーススケジューリング
分岐予測をして複数の基本ブロックを統合して制御依存を減らす方法
基本ブロック:ある分岐命令の直後から次の分岐命令までの命令列
制御フローグラフ:プログラムを基本ブロックの間の依存関係として表現したもの
ソフトウェアは分岐予測に失敗したらまた元に戻さなきゃいけないが、それでもやる価値はある。
1.実行履歴などによって実行される確率の最も高い分岐パターンを調べる
2.そのパターンの上にある基本ブロックを統合する。これをトレースという。
3.トレースに命令スケジューリングを施すことで、トレースなの実行効率を高める。
4.それによってトレース以外に分岐する場合が生じる不都合を防ぐため、分岐先の入り口に補正用のコードを入れる。これをブックキーピングという。
5.トレースを除いた制御フローグラフにおいてこれらを繰り返す。
DeeperLecture
静的最適化
-追加ハードウェア不要
-2倍,3倍の性能が簡単に得られる
-スーパスカラの並列機構を最大限に使う
昔の最適化との違い
-レジスタ数が多い
-複雑な命令がない(RISC)
-投機の技術が進んでいる
アウトオブオーダ処理
・アウトオブオーダ処理
-プログラムの意味を変えない範囲で命令実行・完了の順序を変更し、並列度を上げる処理
-動的スケジューリングの一種:実行時に行うスケジューリング
-アウトオブオーダ処理:命令をEステージに入れる順番を入れ替える
-アウトオブオーダ完了:実行結果をレジスタに格納する順番を入れ替える
アウトオブオーダ処理
命令ウィンドウ:実行可能な命令を呼び出す機構、今や当たり前
命令ウィンドウが1つの場合は集中型と呼ぶ
しかし、これだけの高速化では満足できない。
アウトオブオーダ処理や並列処理をすると、データ依存がこれまでの種類以外にも出てくる。
・フロー依存(真の依存関係):命令Aで書き込んだ値を後続の命令Bで読み出すことでおこるAからBへの依存関係
・逆依存:命令Aで読みだしたレジスタに後続の命令Bが書き込むことでおこるAからBへの依存関係
・出力依存:Aで書き込んだレジスタに後続の命令Bが再度書き込みを行うことで起こるAからBへの依存関係
逆依存と出力依存は主にレジスタ数の不足からくる依存である。
レジスタリネーミング:レジスタ番地の付け替えによる逆依存、出力依存の解消、ハードウェアでやる(ソフトウcえあだとやりきれない)
-ソフトウェア
-マッピングテーブル
-リオーダバッファ
ソフトウェアによるレジスタリネーミング:機械語によるプログラムの書き換え
問題点
1.機械語プログラムで指定できるレジスタ数には限界がある(32まで)
2.CPUのアーキテクチャの細部にプログラムが影響を受けるので透過性・互換性が失われる
スーパーコンピューターなどの世界を相手にする競争をするためには互換性や透過性は無視して、キャッシュやアウトオブオーダなどを意識してプログラムを書く。
C言語でもこういったプログラムを書けるし、機械語ではもっと柔軟に書ける
3.機械語プログラムの変換の手間がかかる
マッピングテーブル:逆依存が起こりそうなレジスタを別のレジスタに割り振る,
ハードウェアの機構である、renameというステージが入る
リオーダバッファ:パイプラインを伸ばさなくて済む、複雑
マッピングテーブルもリオーダバッファも、命令ウィンドウに行く前にレジスタの番号をつけかるという機構である
プロセッサの性能:クロックあたりの平均命令実行数✖️クロック周波数
命令セットが変わると結構変わるが、あまり変わらない現代では上記の定義で良い
クロックあたりの平均実行命令数
・増やす方法
-フォワーディング
-命令スケジューリング
-分岐予測
-キャッシュ
-命令レベル並列処理
-アウトオブオーダ処理
・減る要因
-分岐予測の失敗
-キャッシュミス
-TLBミス
-ページフォると
-ハザード
クロック周波数
・パイプラインの各ステージの複雑さによって決まる
DeeperLecture
アウトオブオーダ+リネーミングの先にあるもの
-マルチスレッド、SMT(複数のスレッドをパイプラインに入れる)
-マルチコア、メニーコア(複数のプロセッサによる並列処理)
-超並列処理(スーパコンピュータ)
入出力と周辺装置
周辺装置の分類
入力:キーボード、マウス、ジョイスティック、マイク、イメージスキャナ、カメラ、ビデオ。センサ類、GPS受信装置、cd-rom,dvd-rom
出力:液晶ディスプレイ、プリンタ、スピーカ
入出力:フロッピーディスク、磁気ディスク、cd-rw、光磁気ディスク、磁気テープ、モデム、LAN
液晶ディスプレイ:電子を磁石で曲げて色を出す
磁気ディスク:シーク、ローテーション、読み出し/書き込みという手順でデータを読み出す、シークが律速段階である
ノートpcの中:キーボード、ディプレイ、認証デバイス、タッチパッド、CPU、バッテリ、チップセット、セキュリティチップ、メモリ、補助記憶装置、HDD/SSD
データ転送の手順
1.ポーリングまたは割り込みによる入出力の軌道
2.前処理
3.命令またはDMAによる主記憶・周辺装置間のデータ転送
4.後処理
ポーリング(見回りのこと):CPUが定期的に順番に周辺装置を見回って、入出力の要求がルカどうかを確認する方式、実装が簡単、OSがこれを扱う、要求がなくてもポーリングするので無駄になることがある
割り込み:周辺装置からCPUに対して割り込み信号を入れ、例外処理を要求して空いて入出力をおこなわせる方式、待ち時間や見回り時間の問題は解決
割り込みの調停
1.集中アービタ方式
2.デイジーチェイン方式
集中アービタ方式(ちょうていき):先ずはコントローラの優先度を決める、(インターネットよりはハードディスクの方が高いというように)
デイジーチェイン方式:集中型アービタが不要で簡単だが、優先度がCPUに近い順で固定される
データ転送
1.入出力専用命令を使ってデータ読み出しまたはデータ書き込みを行う
2.周辺装置にメモリアドレスを割り振り、メモリのロード・ストア命令でデータの読み書きを行う
3.データ転送専用のハードウェアを使って、CPUを介さずに周辺装置と主記憶の間で読み書きを行う
DMA
1.CPUがDMAコントローラノメモリアドレスレジスタ、アドレスカウンタニソレゾレDMAの開始アドレス、転送量を書き込み、DMA転送を支持する
2.CPUはバスアクセスをやめ、DMACがバスの主導権を取ってデータ転送を行う。
3.ACが0になったところでDMACは転送を終了し、バスの制御をCPUに返す
例外処理:例外の要因
ハードウェアエラー
・電源エラー:プログラムの終了
・バスエラー:プログラムの終了
命令実行による例外
・オーバーフロー:プログラムの終了
・ページフォールト:ページスワップ
・TLBミス:TLBエントリ読み込み
・アドレスエラー:プログラムの終了
・メモリ保護違反:プログラムの終了
・未定義命令実行:未定義命令処理ルーチンの実行
・システムコール:カーネルプログラムの実行
プログラム外割り込み
・入出力要求:データ転送の後復帰
・タイム割り込み:プロセススイッチなど
ハードウェアエラーが優先度が最も高く、次に命令実行による例外、最後にプログラム外割り込み、という順番になる
例外処理の手順
1.例外処理の要因が発生したら、CPUが受け付けるかどうか決める。複数の要因が重なったら最も高い優先度の要因を1つ選択する
2.受け付けることが決まった現在実行中のプログラムの状態を退避する。具体的にはデータレジスタ、PC、状態レジスタなどをメモリ上の適切な場所に退避する。
3.例外処理のカーネルプログラムを起動する。カーネルプログラムは例外の要因を知って、必要な処理を行う。
4.例外処理が終わったら、必要に応じて、PCなどの値を復帰し、元のプログラム実行に戻る