一般的に行なわれていることだが、ロードストアユニットの側には、データキャッシュが搭載されており、隣接する既にロードされている値があれば、キャッシュを参照することでわざわざCPUの外にアクセスすることなくデータをレジスタに格納することができる。 この機能が現在の自作CPUに無いので、とりあえず作ってみた。
まず、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スコアが得られた。 ログを見てみると、殆どのロードアクセスが消えている。しかし、ストアアクセスは必ず生じる。 これらについて、無駄が他にも無いか見てみよう。