読者です 読者をやめる 読者になる 読者になる

FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://sites.google.com/site/fpgadevelopindex/

キャッシュコヒーレンシ理解のために資料を漁ったら昔のスライドが出てきたので公開する

ちょっと事情があって、マルチプロセッサのキャッシュコヒーレンシについて復習していたら、そういえばこれ研究室の輪講で発表したな。死ぬほど長い輪講資料作ったけどどこに行ったんだろうと思ってGoogle Drive探してたら見つかったので、せっかくだしディスクの肥やしにするのももったいないので公開することにした。

それにしても、過去の自分が作ったとはいえ、死ぬほど長い。 過去の自分は、こんなにも長い資料が作れていたんだなあ。。。

www.slideshare.net

ヘネシー&パターソン コンピュータアーキテクチャ 定量的アプローチ 第5版

ヘネシー&パターソン コンピュータアーキテクチャ 定量的アプローチ 第5版

キャッシュコヒーレンシとは

マルチプロセッサ上には、書くコアにキャッシュが載っていて、直近で利用しているデータはキャッシュにたまっており、メモリアクセスのバンド幅を抑え、レイテンシを小さくする役割を持っている。 ただし、同じ場所のデータを複数のコアがキャッシュに持っていて、一方を書き換えてしまった場合、矛盾が生じてしまう。これをどう解決するの?という問題。

f:id:msyksphinz:20160407022222p:plain

まずCPU-Aが主記憶からアドレスXを読み込んでくるのだけれども、次にCPU-BもアドレスXの値を主記憶から読み込む。 ここで、CPU-AがアドレスXに0を書き込んでしまうと、CPU-Bはその事実を知らないものだから、アドレスXの値をずっと0と勘違いして進んでしまうことになる。

さて、これをどう解消しようかね、という話なのだが、資料の中ではキャッシュスヌーピングプロトコルというものを紹介している。 ようするに、キャッシュからメモリへ書き戻す操作をそれぞれのキャッシュがスヌーピング(盗み見)ており、自分が持っているデータが書き換わったら、自分の持っているキャッシュの内容を破棄して、矛盾が生じないようにする、という訳だ。

f:id:msyksphinz:20160407022629p:plain

この問題を解決するための方法の一つとして、Writeインバリデートプロトコルというものが存在する。 これは、各コアが同じアドレスXのデータを持っていたとすると、あるコアがそのアドレスにデータを書き込むと、すべてのコアがXを保持しているキャッシュのラインをインバリデート(削除)する、という方法だ。これで、矛盾は発生しない。コア0以外は、もう一度アドレスXが必要になった場合は主記憶にもう一度取りに行きなさい、という訳だ。

この時に、別のコアがアドレスXに対してリードリクエストを出した時に、どこから真の値を読み出すかというのは問題になる。

ライトスルーキャッシュなら問題ない。真の値は常に主記憶上に存在するからだ。 しかし、ライトバックキャッシュの場合は、真の値はキャッシュ上に残っている可能性がある。そうすると、別のコアのリクエストに対して、そのキャッシュ自身が反応することがあり得る。 ただし、これが一般的なのかはよく知らない。

f:id:msyksphinz:20160407023309p:plain

f:id:msyksphinz:20160407023333p:plain

次に、コヒーレンシをとるためのプロトコルについてみていく。ヘネパタでは、以下のステートマシンが紹介されている。

f:id:msyksphinz:20160407023444p:plain

例えば、各コアがあるアドレスの値を共有している状態であったとしても、その値を読み込む分には何の問題もない。

f:id:msyksphinz:20160407023530p:plain

P1とP3が同じ値を共有していたとして、P1がその値に書き込みを行うと、バス上にインバリデートが発行され、P3の値は無効化されてしまう。

f:id:msyksphinz:20160407023702p:plain

このとき、P3はバスからのリクエストに応じて、該当するキャッシュラインをインバリデートする訳だ。

f:id:msyksphinz:20160407024021p:plain

こういうのはさらに厄介だ。すでにP3がキャッシュに対して書き込みを起こしているのに、別のP1が同じアドレスに対して書き込みを起こしてしまった。 すると、P1はP3にライトインバリデートを伝える。するとP3は当該アドレスのラインを主記憶に書き戻し、そのデータをP1が拾って、さらにModified状態に変更する。

f:id:msyksphinz:20160407024151p:plain

そこから先も、パフォーマンスについていろいろ書いてあるので読んでほしい。僕はもう疲れた。

とにかく結論は、

f:id:msyksphinz:20160407024407p:plain

ふーん。