CSAPP 第6章 メモリ階層
RAMには2種類存在する
- スタティックRAM
- ダイナミックRAM
この2つの大きな違いは、値を定期的に書き込む必要があるかないか
スタティックRAM
フリップフロップ回路を用いて値を保存させる。
そのため放電の考慮を必要とせず、値が常に保存されていることを保証する。
しかし、回路を必要とするため、DRAMに比べて一つの値を管理するための物理面積が大きい
そのため多くの値を保存することができない。
ダイナミックRAM
前提としてコンデンサは回路内部を流れる電流によって漏電などを起こす。
これによりコンデンサ内に値を保持している、DRAMは値を失ってしまう。
そのため、DRAMは同一の保存データを繰り返し書き込む必要があり、これによって値を保存しておくことができる。
これをリフレッシュという。
DRAMはその性質上、リフレッシュをする時間が存在する。
リフレッシュ中は書き込んだデータが保持されている保証はないので、
その時間帯において、CPUからの読み込み/書き込みをブロックする必要がある。
この性質から、メモリの読み込み速度が低下する事がある
DRAMはピンを使って各データをメモリコントローラーを経由して、CPUに送信する
DRAMから値を取り出すときはRow(行)にアクセスするRAS(Row Access Strobe), Column(列)にアクセスするCAS(Column Access Strobe)を使用する。
例えばスーパーセル(2, 1)にアクセスしたいとする
その場合の処理の順序は以下のようになる
- CPUからRASを、行アドレス
2
で送信する - Row Address Bufferが行アドレス2の値をすべてバッファする
- CPUからCASを、列アドレス
1
で送信する - Rowバッファから列1を取り出し、dataピンによって送信を行う
昔のメモリはDIP(Dual Inline Package)と呼び、マザーボードにはんだ付けされている状態だった。
この状態だとメモリを後で増設しようと思ったときにすでにマザーボードとメモリがくっついているので、取り外しができなくメモリの増設などができない状態であった。
そのため新しく開発されたのがSIPである。
SIP(Single In-line Package)の略で、マザーボードと接合部分が一つしか存在しなく取り外しが可能なものだった。
これによって増設などが容易に行えるようになったが、接合部分が少し貧弱だったので、折れてしまうなどの問題が発生した。
そこで少し実装コストが高いが強度に優れたSIMM(Single In-line Memory Module)が登場した。
現代で使っているメモリもこの形状である。
SIMMは 8bit幅にしか対応しない構造だったため、もっと多くのデータをやり取りしたいという要望を叶えるものではなかったので、pinの数を増加した 64pin SIMMや88pin SIMMなどが開発された。これによりより多くのデータを保存することができた。
この流れを受けて登場したのがDIMM(Dual In-line Memory Module)である。
SIMMとDIMMの最大の違いは「信号ピンが片側か両方か」というところである。
DIMMは基盤の表と裏で別々の信号ピンが割り当てられている。
これにより大きさなどがほとんど一緒な72pin SIMMとDIMMでもDIMMのピン数は168pinとなっている
DIMMの開発要因としては64bit CPUの普及によりバス幅が64bitになったという点にある。
これによりメモリモジュールが64bit幅になることが期待された。
現在もメモリのバス幅は64bitのままである
バス幅
制御回路が一度の動作で運べるbit数
現代のSSDはNAND型と呼ばれる形式を用いている
SSD全体の構造
NANDキャッシュの仕組み
ブリッジ回路
チップセット。バスをCPU/メモリなどの主要機器にデータの受け渡しを行うI/Oコントローラー。
CPU/メモリなどの主要機器に近い範囲にあるチップセットをノースブリッジ。
I/Oデバイスなどに近い集積回路をサウスブリッジと呼んでいたが、現在はマザーボードに設置されているチップセットは一つになっているのでその名称は使われていない。
HDD
ディスクストレージの中身には複数のディスクと、中の磁気を読み取るアームが存在している。
ディスクの中には微粒子が入っていて、その粒子が磁力的な特性を持ち、一つの方向に傾いていることにより、0と1を区別することができる。
磁力アームで磁気の方向性を読み取ることにより、0と1を判別してデータを読み書きする
DMA(ダイレクト・メモリ・アクセス)転送
CPUを介さずに、メモリとディスク間でデータの転送を行うこと。
DMA転送が終わった際に、CPU側に割り込み信号を行って通知する。
それまでは非同期で処理を行う事ができるので、並行処理を実現する。
現在のストレージ・テクノロジーにおいてボトルネックとなっているのはストレージ(HDD, SSD)とDRAMである。
SRAMの進化はCPUの成長速度に追いついているのでボトルネックにはなりにくい。
CPUはシングルコアでの成長が限界に達したことにより、マルチコア化に踏み切りレイテンシではなくスループットを向上させることで性能限界を上げてきた。
局所性
参照リソースを集中することにより、速度を向上させる手法
2次元配列に対してのアクセスとして以下のような方法だと速度が早くなることが挙げられる。
シーケンシャルパターンとストライドパターンの違い
メモリ階層
bitを保持するデバイスは複数存在する。
より小さくて速く動作するものは単価がたかく、逆は安い。
そのためピラミッド構造にして表すことが多い。
この2ページに図が存在する
キャッシュ
キャッシュとは、低速な記憶装置や伝送路から読み出したデータのうち、直近に読み込んだものや使用頻度が高いものを高速な記憶装置に複製しておくこと。また、その際に使われる高速な記憶装置や、複製されたデータそのもののこと。
https://e-words.jp/w/キャッシュ.html#:~:text=キャッシュとは、低速な,削減することができる。
キャッシュヒット
あるレベルk + 1から特定のデータオブジェクトを検索するときに、もしレベルkにそのデータがキャッシュされていたら、それは キャッシュヒット とよばれ、読み出す速度が速くなる
レベルの例としては、DRAMにあるデータを探すときにL3キャッシュの方をまず見に行くといったようなものである。
もしなかった場合、それは キャッシュミス と呼ばれ、下位レベルのブロックをフェッチする。
もし上位キャッシュがすでにいっぱいであった場合、ブロックを上書きする。
これをreplace, evict(立ち退き)と言ったりもする
キャッシュの構造はウェブから始まっているものである
ダイレクトマッピングの話
セットアソシアティブキャッシュ
ダイレクトマッピングはキャッシュミスを多く発生させてしまうことでreplaceの時間がかかってしまう。
これを解決する方法として、セットアソシアティブキャッシュというものが用いられる。
ダイレクトマッピングはメモリアドレス全体に対してCache sizeの分だけindexを分割することで、格納位置を定義していたが、セットアソシアティブは格納位置を拡張する。
ダイレクトマッピングの場合はあるメモリアドレスに収納している値は、キャッシュインデックスの一意の場所に特定される。
メモリアドレス 1に入っているデータは、必ずキャッシュインデックスの1に格納される。
セットアソシアティブの場合は、メモリアドレス 1に入っているデータはキャッシュインデックスの1 or 2に格納される。これを2 way セットアソシアティブという。つまりメモリアドレスに対して、2つの格納できるキャッシュが存在するということ。当然3way 4 wayも存在する。
ダイレクトマッピングだと、たまたま複数回使うメモリが1つでもかぶってた場合、そのミスを取り返す術はなく、毎回キャッシュの入れ替えが起きてしまう。(スラッシング)
そのためセットアソシアティブにより、キャッシュマッピングに余裕をもたせることで速度低下を妨げることを保証することができる。
ただway数が大きければフルアソシアティブの欠点である、全探索の速度低下やプロセッサチップの拡大のデメリットも被るため、その真ん中のいいとこ取りをする必要がある
キャッシュreplaceが発生するときに、果たしてどのキャッシュに入っているブロックを置き換えるかという問題もある。
ライトスルー、ライトバック
ライトバックの場合、ダーティビットというものが存在する。
データがキャッシュにしか存在しないので、その値が書き換わってしまうと値がなくなってしまう。
そのため、キャッシュリプレイスが行われるタイミングでキャッシュに保存されている値をメモリに書き込む
これにより値の消失を防ぐ。
これはダーティビットと呼ばれるバリッドビットを持つことにより実現可能となる
キャッシュは命令も保持することができる。
命令のキャッシュをI-Cache、データのキャッシュをD-Cacheと呼ぶ
プログラマがキャッシュの恩恵を受ける方法は3つ
- ループに注目
- ストライド1でアクセスする
- ローカル変数をなるべく使うようにする