このページの本文へ

ロードマップでわかる!当世プロセッサー事情第77回

キャッシュの実装方式から見える AMDとインテルの置かれた状況

2010年11月15日 12時00分更新

文● 大原雄介(http://www.yusuke-ohara.com/)

  • この記事をはてなブックマークに追加
  • 本文印刷

もうひとつのプリフェッチ手法 Explicit Prefetch

 Implicit Prefetchとは異なる方法として、「Explicit Prefetch」(明示的プリフェッチ)と呼ばれる方法もある。Implicit Prefetchはあくまでも、メモリーアクセスのされ方などからキャッシュコントローラーが「次はこのあたりをプリフェッチしよう」と推定して行なうものだ。だからアクセスパターンによっては、必ずしもうまくプリフェッチがかかるとは限らない。

 しかし、プログラム中から明示的にプリフェッチをかける、「プリフェッチ命令」と呼ばれるキャッシュ制御命令も使う手もある。これがExplicit Prefetchの概念だ。筆者の記憶が正しければ、これがx86 CPUに搭載されたのは、AMDの「Enhanced 3DNow!」が最初で、続いてインテルも「SSE2」でこれをサポートした。

 プリフェッチ命令を使うと、プログラムがキャッシュに取り込んでおきたいメモリー領域を明示的に指定し、強制的に2次/3次キャッシュに取り込める。もっとも「どのくらい取り込むか」というのは、当然ながらそのCPUが取り込んだデータを処理するのに必要な時間や、2次/3次キャッシュの容量にも関係してくる。

 容量が少ないキャッシュで、派手にプリフェッチしても無駄だ。逆に大容量3次キャッシュを搭載する昨今のCPUで、16KB程度のサイズをちまちまプリフェッチしても、性能改善にはそれほど役立たない。そのためExplicit Prefetchは、特定のCPUアーキテクチャー向けにはいい方法であるが、汎用的(つまりどんなCPU上で動作するかわからない)プログラム相手では、効果を発揮するのが難しいものなのだ。

 余談であるが、x86 CPUではImplicit Prefetchを「Hardware Prefetch」、Explicit Prefetchは「Software Prefetch」と呼ぶのが一般的である。Implicit Prefetchはキャッシュコントローラー(および演算パイプライン中のPrefetcher)がハードウェア的に実行するからHardware Prefetch。対するImplicit Prefetchは、プリフェッチ命令、つまりソフトウェアで実行するからSoftware Prefetchというわけだ。

キャッシュ内データの保持の仕方は
2つの手法に分かれている

 ところで、前ページの図1~3は、「Inclusive Cache」(包括的キャッシュ)と呼ばれる方法である。これに対比するものが、「Exclusive Cache」(排他的キャッシュ)、あるいは「Victim Cache」と呼ばれる技法である。x86で見た場合、AMDの「K7」(Athlon)以降のアーキテクチャーはすべてVictim Cacheを採用し、それ以外(インテル/VIA、AMDの「K6」シリーズまでの製品など)はInclusive Cacheを採用している。

 両者の違いは何か? 簡単に模式化したのが図5と6である。図5がInclusive Cacheで図6がExclusive Cacheである。わかりにくいかもしれないが、ようするに「同じデータを複数のキャッシュで保持する」のがInclusive Cacheで、保持しないのがExclusive Cacheというわけだ。これは、キャッシュの利用効率を重視するか、アクセス時のレイテンシーを重視するかの違いである。

図5 図6
図5 Inclusive Cacheでのデータの持ち方。1次キャッシュと同じデータが2次/3次キャッシュにも含まれる図6 Exclusive Cacheでのデータの持ち方。1次キャッシュのデータは、2次/3次キャッシュにはない

 Inclusive Cacheの場合、例えば1次ミス/2次ミス/3次ヒットという状況であれば、3次キャッシュに入っているデータがそのまま1次キャッシュにキャッシュフィルされることになる(アーキテクチャーによっては2次キャッシュにも)。この際に、3次キャッシュに入っていたデータは基本的にそのままだ。図5で言えば、一番下のべた塗り部分がこれに相当する。この方式の有利な点は、読み込み時のレイテンシーが短縮できることだ。

 1次ミス/2次ミス/3次ヒットのケースで動作の流れを見るとこうなる。

  • ① 1次タグを検索→1次キャッシュミス
  • ② 2次タグを検索→2次キャッシュミス
  • ③ 3次タグを検索→3次キャッシュでヒット
  • ④ 3次キャッシュからデータをフェッチしてCPUパイプラインに取り込み
  • ⑤ フェッチしたデータを1次キャッシュにもフィル
  • ⑥ フェッチしたデータを2次キャッシュにもフィル

 ④~⑥は実質的に並行して実施できる。一方、書き込みはその分ちょっと面倒である。例えば1次/2次/3次で保持しているデータを書き換えた場合、その手順はこうなる。

  • ① 1次タグを検索→1次キャッシュヒットならば、そのラインを更新
      1次キャッシュミスなら1個ラインを空けて、そこに書き換えたデータをフィル
  • ② 2次タグを検索→1次キャッシュヒットならば、そのラインを更新
      2次キャッシュミスなら1個ラインを空けて、そこに書き換えたデータをフィル
  • ③ 3次タグを検索→3次キャッシュヒットならば、そのラインを更新
      3次キャッシュミスなら1個ラインを空けて、そこに書き換えたデータをフィル
  • ④ 3次キャッシュで書き換えたデータをメモリーコントローラー経由でメモリーに反映

 キャッシュコントローラーの作り方次第では、②~④を並行処理できる可能性もあるが、読み込みよりはちょっと面倒だ。それでも、これはまだ簡単な方である。

この連載の記事

注目ニュース

ASCII倶楽部

最新記事

プレミアムPC試用レポート

ピックアップ

ASCII.jp RSS2.0 配信中

ASCII.jpメール デジタルMac/iPodマガジン