FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

アウトオブオーダのCPUを作ろう - ロードバッファによるメモリアクセス数削減

一般的に行なわれていることだが、ロードストアユニットの側には、データキャッシュが搭載されており、隣接する既にロードされている値があれば、キャッシュを参照することでわざわざCPUの外にアクセスすることなくデータをレジスタに格納することができる。 この機能が現在の自作CPUに無いので、とりあえず作ってみた。

f:id:msyksphinz:20150221033658j:plain

まず、RSからメモリアクセス要求が渡されると、それがロード命令かストア命令かを判定する。そして同時に、LSU-DataBufferのインデックスを探索し、テーブル内に該当するアドレスのデータを保持しているかどうかを調査する。 ロード命令かつ対象アドレスのデータが既にテーブルに入っているならば、そのテーブルからデータを取り出して、そのままWBに渡して終了である。 もし対象アドレスのデータがテーブルに入っていなければ、そのテーブルではなく外部にデータを取りにく。この最、既にロードストアユニットにはLS-Buffer(ロードストア要求のバッファ)があるので、ここに登録される。 そして、メモリアクセスが完了して当該データが入手できると、同時にテーブルにも登録して、以降のアクセスからは外部からロードしなくても良くする。

さらに、ストアの場合にも、常にテーブルデータを最新にするために、テーブルの更新を行う。テーブルの更新と同時に、常にAXIの外にもストア要求を出すようにしている。 つまり、ストアについては必ず外部へのアクセスが発生する仕組みだ。これは、コヒーレンシを保持するためというか、ストアをLSU-DataBuffer内だけで保持しているときに、新しいテーブルの挿入により既存のテーブルをスピルアウトする場合、ストア命令が入ってしまい機構的に難しいからである。とりあえずここでは簡単な実装を採用してある。

ダイレクトジャンプ型 分岐命令予測 比較型分岐 命令予測1 比較型分岐 命令予測2 分岐命令 RS2段 ALU 2並列 LSU内バッファ Coremark サイクル数 CMK値
          760722 1.31
        759183 1.32
      741199 1.35
      739813 1.35
    712570 1.40
    632125 1.58
    594570 1.68
  573741 1.74

上記が測定結果だ。 下から2つが今回追加した測定結果。ALUを2並列にしなくても効果あり、2並列で実行すると、さらに高いCoremarkスコアが得られた。 ログを見てみると、殆どのロードアクセスが消えている。しかし、ストアアクセスは必ず生じる。 これらについて、無駄が他にも無いか見てみよう。