リザベーションステーションを実装していると、連続して同じレジスタを使うような命令が連続する場合、通常の実装ではどうしてもストールが1サイクル入ってしまう問題があった。
上記のような演算器の実装をしていると、どうしても演算器の結果の直後にFFが入っておりリザベーションステーションへの書き込みが1サイクル遅れてしまう。これにより、 リザベーションステーションから命令が発行されるタイミングが1サイクル遅れ、依存関係のある連続する命令に1サイクルの空きが発生してしまう。
OP0 r3, r2, r1 // r3=op0(r2, r1) OP1 r4, r3, r5 // r4=op1(r3, r5)
このr3のレジスタ依存のフォワーディングを解決するために1サイクル待たなければならないという訳だ。これは性能に重大な影響を及ぼしそうなので、以下の資料を参考に、1サイクル早く命令を発行できるような機構を実装する。
Chip Architect: Detailed Architecture of AMD's Opteron
リザベーションステーションは、ALUが演算結果を生成する1サイクル前に、演算命令のタグをバスに流すようにしている。これを受け取ったリザベーションステーションは、 「1サイクル後に欲しいデータが入手できるはず」という情報のもと投機的に命令をリザベーションステーションから発行してしまう。 これは、リザベーションステーション内で「データのフォワーディング」をする必要が無く、「タグ比較」のみで命令を発行してよいかを判断できるため、回路的に大きな負荷にならないという利点がある。
本当はALUだけでなく、LSUにも同様の機構を実装すると効果がありそうだが、とりあえず現状の自作プロセッサに対して、以下のタグフォワーディングパスを実装して性能向上を観測した。
- ALU0 --> ALU1
- ALU1 --> ALU0
これにより、全てのALU同士の演算結果はストールすることなく実行することが出来るようになる。
サイクル数
前回の分岐予測改善時と比較して、サイクル数がどの程度改善しているのか計測した。
Cycle | Rate | |
---|---|---|
2-state Branch Prediction | 49889 | 100% |
4-state Branch Prediction | 45528 | 91.2% |
Branch + Tag Forwarding | 43373 | 86.9% |
タグフォワーディングにより、性能は約4%改善した。
IPC経過
ちょっと分かりにくくなってきたなあ。前半のIPCが改善されてきた気がする。ただし後半はあまり伸びがない。 要改善。