FPGA開発日記

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

アウトオブオーダプロセッサの性能解析(リネーミングユニットから命令の受け渡し)

msyksphinz.hatenablog.com

前回の性能解析でそもそもバグとして残っていた部分だが、アウトオブオーダプロセッサが実行中の命令というのはリオーダバッファで管理されており、もちろんこのリオーダバッファが溢れるような状態になると命令の発行を中止しなければならない。

リオーダバッファへの格納は、リネーミングが終わった後、そしてリザベーションステーションへの命令格納と同時に行われるような設計にしている。つまり、リネーミングステージは、リオーダバッファの空き状態と、リザベーションステーションの空き状態を監視しながら命令の発行を行う必要がある。

さらに具体的に言うならば、リネーミングステージは、リザベーションステーションとリオーダバッファの両方からREADY信号がもらえれば発行することが出来る。 問題は受け側(リザベーションステーション・リオーダバッファ)の方で、どちらかが受け取れるからといって勝手に受け取ると整合性が合わなくなる。 ここの実装をサボっていたためリグレッションテストで問題が発生していた。

f:id:msyksphinz:20170106004917p:plain

さてここの実装だが、結局リザベーションステーションとリオーダバッファの両方が空いていないと命令が受け取れないため、互いのユニットから空き情報をやり取りしてそれぞれのREADY信号を落とすようにした。

このような実装ならば別にREADYを2つのユニットから出さずに統一して出せそうなものだが、そこまでまだリファクタリング出来ていない。

リオーダバッファの空き容量問題

リオーダバッファの空き容量も問題になる。たとえば、64エントリのリオーダバッファを持っているとして、そのうち62エントリを利用しているものとする。

一応満杯ではないのだが、次に4命令分発行されると受け取れなくなる。そこで、64エントリならば、1サイクルで受け取れる最大の命令数よりも残りエントリ数が小さくなると、自動的にREADYを下げるように設定する。

大まかに実装すると、大体こんな感じだ。ただしこの実装はひどい。

  assign RN_ROB_READY = (cm_status_inflight_in[ 0] + cm_status_inflight_in[ 1] + cm_status_inflight_in[ 2] + cm_status_inflight_in[ 3] +
                         cm_status_inflight_in[ 4] + cm_status_inflight_in[ 5] + cm_status_inflight_in[ 6] + cm_status_inflight_in[ 7] +
                         cm_status_inflight_in[ 8] + cm_status_inflight_in[ 9] + cm_status_inflight_in[10] + cm_status_inflight_in[11] +
                         cm_status_inflight_in[12] + cm_status_inflight_in[13] + cm_status_inflight_in[14] + cm_status_inflight_in[15] +
                         cm_status_inflight_in[16] + cm_status_inflight_in[17] + cm_status_inflight_in[18] + cm_status_inflight_in[19] +
                         cm_status_inflight_in[20] + cm_status_inflight_in[21] + cm_status_inflight_in[22] + cm_status_inflight_in[23] +
                         cm_status_inflight_in[24] + cm_status_inflight_in[25] + cm_status_inflight_in[26] + cm_status_inflight_in[27] +
                         cm_status_inflight_in[28] + cm_status_inflight_in[29] + cm_status_inflight_in[30] + cm_status_inflight_in[31] +
                         cm_status_inflight_in[32] + cm_status_inflight_in[33] + cm_status_inflight_in[34] + cm_status_inflight_in[35] +
                         cm_status_inflight_in[36] + cm_status_inflight_in[37] + cm_status_inflight_in[38] + cm_status_inflight_in[39] +
                         cm_status_inflight_in[40] + cm_status_inflight_in[41] + cm_status_inflight_in[42] + cm_status_inflight_in[43] +
                         cm_status_inflight_in[44] + cm_status_inflight_in[45] + cm_status_inflight_in[46] + cm_status_inflight_in[47] +
                         cm_status_inflight_in[48] + cm_status_inflight_in[49] + cm_status_inflight_in[50] + cm_status_inflight_in[51] +
                         cm_status_inflight_in[52] + cm_status_inflight_in[53] + cm_status_inflight_in[54] + cm_status_inflight_in[55] +
                         cm_status_inflight_in[56] + cm_status_inflight_in[57] + cm_status_inflight_in[58] + cm_status_inflight_in[59] +
                         cm_status_inflight_in[60] + cm_status_inflight_in[61] + cm_status_inflight_in[62] + cm_status_inflight_in[63] < 60);

これはビットカウントの回路を実装することでもうちょっとマシになりそうだ。とりあえず、上記の修正を施すことで、リグレッションテストで問題になっているものの1つを解決することが出来た。次は、全体を流してさらに問題を洗い出して行きたい(が、時間がない)。