まあいつかの段階で自作CPUのスケジューラを変更しようと思っているのだが、これをどのようにしようかいろいろ思いを巡らせている。 アウトオブオーダのフロントエンドはあまり得意ではないので、どうやって作ればいいのか悩んでいる。
現在の実装
- Issue Unitが各モジュール (ALU / LSU / FPUなど)に分散している
- Matrix Schedulerを導入したいが、これをどのように変更しようか?
まず、Matrix SchedulerはIssue Windowの大きさのみを管理するということなので、仮にその大きさを16として(Reloadedの実装を含まずにNaiveな方法で)で導入することを仮定しよう
依存関係を解決の検出は、これまでに使用しているSchedulerの通知方法を使えばいいはずだが、
- これまでは、物理レジスタへの書き込みの2サイクル前にEarly Notificationを出力して、先行して発行させていた。
- LSUによるSpeculative Missが起きない限りはこの方法がいける
- なので、Matrix SchedulerのWakeupの実際は、Wakeup Logicが動いたタイミングというよりは、実際のパイプラインがResultを生成する直前にアップデートしなければならないのか?
- そうでないと、長いパイプラインの命令でA-->Bの依存関係があり、Aを発行した後すぐにBを発行するとBのデータが間に合わない
- これまでは、物理レジスタへの書き込みの2サイクル前にEarly Notificationを出力して、先行して発行させていた。
Speculative Missが発生した場合
- これまでは、分散したSchedulerにおいて、各命令の発行エントリがステートマシンを持っており、Speculative Missを検出するとそこで制御していた
- 例えばLSUの場合、EX1でEarly WakeupでResultの依存する命令をWakeupするが、次のサイクルのEX2でSpeculative Missが生成されると、止めることができる
- 命令Bは命令Aに起こされるが、次のサイクルでSpeculative Missを検出するともう一度待機状態に戻ることができる。
A --> ISS --> EX0 --> EX1 --> EX2 --> EX3 Early Wakeup Result [Speculative Miss] B "Detect Wakeup" Stop
これは2サイクル遅れでもなんとかなるはずで、Bが発行されてからEarly Wakeupまでの余裕があるためBに依存するさらに先の命令がWakeupすることはない。
A --> ISS --> EX0 --> EX1 --> EX2 --> EX3 "Early Wakeup" "Result" [Speculative Miss] B "Detect Wakeup" ISS --> Stop
- で、これをMatrix Schedulerでやるとどうなるかという話だが、行毎にBackupが取れるようにしておき、投機的なWakeupが発生した場合はBackupを取るということになるのだろうか?