自作CPUの性能向上のために、これまで単一バンクだったデータキャッシュを作り変えてみよう。
一般的に高性能プロセッサでは複数のLSUパイプラインが同時にデータキャッシュにアクセスする。しかしSRAMは一般的に1ポートしか読み込みポートが存在しないので、 同じSRAMに対して一度に読み出しリクエストを行うとそれは物理的にどちらかを排除しなけれならず、この場合は"Conflict"として、採用されたリクエスト以外は「リトライ」して成功するまで頑張ることになる。
ただしあまりにもぶつかることが多いと性能に直接影響するため、近接しているメモリはそれぞれ「バンク」に分け、同時アクセスを可能とするのが一般的だ。
例えば、256ビットのキャッシュラインを持っている場合、32バイトまでの距離は1つのキャッシュラインに収まることになる。しかし例えば0x00へのアクセスと0x40のアクセスが同時に発生すると、それは32バイトのキャッシュラインを超えるためどちらかがブロックされリトライとなる。 そこでどうするかというと、256ビットのSRAMを4つ並べて同時にアクセスできるように、アドレスマップを以下のようにする。これで4バンクの構成となる。
+----------+----+-------+ | TAG |BANK| Index | +----------+----+-------+ 6 5 4 0
すると、0x00のアクセスと0x40のアクセスはそれぞれ別のバンクへのアクセスとなり同時アクセスが可能となり、性能が向上する。
とりあえず雑に実装したものでDhrystoneを流してログを取ってみる。キャッシュのサイズはバンク前とバンク後で全体サイズが変わらないように調整してある。 一部性能ログからトレースを抜き出したもの。
- バンク化していないもの
" 24386" : { "commit" : { "cmt" : 306, "inst" : 991, "dead" : 189 }, "icache" : { "request" : 716, "hit" : 716, "miss" : 0 }, "dcache" : { "port[0]" : { "req" : 0, "hit" : 0, "miss" : 0, "conflict" : 0 } "port[1]" : { "req" : 0, "hit" : 0, "miss" : 0, "conflict" : 0 } "port[2]" : { "req" : 0, "hit" : 0, "miss" : 0, "conflict" : 0 } "port[3]" : { "req" : 119, "hit" : 93, "miss" : 0, "conflict" : 26 } "port[4]" : { "req" : 244, "hit" : 198, "miss" : 1, "conflict" : 45 } "port[5]" : { "req" : 159, "hit" : 109, "miss" : 0, "conflict" : 50 } }, "branch" : { "execute" : 306, "cmp" : { "execute" : 242, "hit" : 232 }, "uncond" : { "ret" : { "execute" : 32, "hit" : 18}, "others" : { "execute" : 32, "hit" : 32 }}, }, }
- 4バンク化したもの
" 24386" : { "commit" : { "cmt" : 310, "inst" : 1012, "dead" : 212 }, "icache" : { "request" : 707, "hit" : 707, "miss" : 0 }, "dcache" : { "port[0]" : { "req" : 0, "hit" : 0, "miss" : 0, "conflict" : 0 } "port[1]" : { "req" : 0, "hit" : 0, "miss" : 0, "conflict" : 0 } "port[2]" : { "req" : 0, "hit" : 0, "miss" : 0, "conflict" : 0 } "port[3]" : { "req" : 111, "hit" : 106, "miss" : 0, "conflict" : 5 } "port[4]" : { "req" : 213, "hit" : 202, "miss" : 1, "conflict" : 10 } "port[5]" : { "req" : 124, "hit" : 113, "miss" : 0, "conflict" : 11 } }, "branch" : { "execute" : 310, "cmp" : { "execute" : 245, "hit" : 236 }, "uncond" : { "ret" : { "execute" : 33, "hit" : 14}, "others" : { "execute" : 32, "hit" : 32 }}, }, }
LSUの衝突conflict
の数は明確に減った。これは嬉しい。