FPGA開発日記

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

AXIと接続するLSUの実装方法検討(1)

LSUとはLoad Store Unit(たぶん)のことで、メモリアクセスに関わるすべての操作を担当するユニットだ。最もシンプルなものであれば、キャッシュに対するロードストアが出来れば良い。

CPUのパイプラインからの要求に応じて、外部バスを操作してメモリにデータを書き込んだり、メモリからデータを取得してパイプラインに戻す操作を実行する。

プロセッサの命令のうち約1/3はメモリアクセスと言われているくらい、LSUは頻繁に使用される。従って、このメモリアクセスをどのように高速に実行するかがプロセッサの性能を決める大きな鍵になる。 このため、最新のプロセッサではLSUに様々な機能を追加して性能を向上させている。

  • LSU内にラインバッファを保持し、キャッシュの1ラインを同時に取得しておく。同一キャッシュライン内であればメモリにアクセス要求を出すことなく、キャッシュラインからデータを取り出してパイプラインに返すことにより、隣接データアクセスの性能を向上させることができる。
  • LSU内にストアバッファを保持し、ストアしたデータのロードが発生した場合にメモリまでリードリクエストを出さず、LSU内でフォワーディングをする。このため、ロードの時間を省略して動作を高速化できる。
  • ストアマージは、近傍のメモリアクセスのアドレスが同一キャッシュライン上に存在する場合、そのストアをマージして、1つのストア命令として発行する。数回のストアを1回のストアにマージできるため、処理を高速化できる。

最新のプロセッサの場合はLSUは直接外部バスに出る訳ではなく、まずは1次キャッシュ、そして2次キャッシュを通じて外部バスに接続される。 このため、LSUは直接AXIバスを扱うことはなく、LSUと1次キャッシュ間の独自プロトコルで通信することが共通だが、とりあえずここでは外部にAXIアクセスする場合、どのようにすべきかについて考えておこう。

殆どの場合はIFUによる命令フェッチと同一だが、今度は書き込みのことを考えなければならない。 そしてストア命令はメモリアクセスに直結するため、投機的実行をしてはならない。もしストア命令を投機的に実行してメモリに書き込みを起こしてしまった場合、その後にやり直しをすることが出来ないからだ。

このため、以下のような方法を取る。

  1. まず、LSUにデータストア命令を受け取ると、一旦バッファに書き込んで、リオーダバッファに向けて命令完了信号をアサートする。この時点でまだ具体的なストアは行わないが、ストアに必要なデータ(アドレス、データ)は揃っているという状態だ。
  2. 命令コミットユニットは当該ストア命令がコミット可能になると、コミットの実行とともにLSUに向けてコミット完了通知を出す。
  3. LSUはコミット完了通知を受け取ると、LSU内のバッファに格納してあったストア命令の情報を利用してストアを実行する。

このように、LSUとコミット管理ユニットの間で信号の往復が行なわれる。このため多少無駄ではあるが、ストア命令のコミットを必ず待ってからメモリアクセスが実行されるため、投機的にストアが実行されることはない。

もちろん、LSU内にストア情報を格納するためのバッファは複数保持されているため、複数のストア命令を待っている状態も実現できる。このようにして、LSUよりも上位のパイプラインをなるべく早く進めることで、アウトオブオーダ実行を効率化している。