ChampSimというコンピュータアーキテクチャの研究でよく使われている(?)シミュレータがあります。 他のシミュレータと比べてソースコードが簡潔なのはいい点ですが、シミュレーションの正確性はかなり怪しいです。 ソースコードを全部読んで見つけた変な点をメモしておきます(大半は先週今週あたりに直りました)。
ソースコードの問題点
デコード幅がおかしい
不等号を間違えていてデコード幅が1多くなっています。今は直っています。
デコーダーがパイプライン化されていない
このサイクルにデコードした命令数ではなく、デコードステージにあるすべての命令数がデコード幅以下になるようなコードになっています。今は直っています。
何回もフェッチされる
フェッチ完了後に同じキャッシュラインにある命令がフェッチ開始されると、フェッチ中状態に戻ってしまいます。develop
ブランチでは直っています。
命令のスケジューリングがおかしい1
[ROB.head, ROB.size)の範囲のみをスケジューリングしていたため、[0, ROB.head)の範囲の命令はROB.headが一巡するまでスケジューリングされなくなっています。develop
ブランチでは直っています。
SPPというプリフェッチャが間違っている
配列外アクセスをしている部分があります。DPC3に参加したSPP+PPFというプリフェッチャもバグっているらしいです(2020 ISCA p.125)。
キャッシュのレイテンシ設定がおかしい
L2キャッシュでヒットした場合、そのレイテンシはL1D_LATENCY+L2C_LATENCY+L1D_LATENCY
になります。意図したものとは思いづらいです。
分岐命令が全て方向分岐予測器にかけられる
無条件分岐命令であっても、分岐方向予測器がnot-takenだと言えば分岐予測ミスになります。 逆に、間接分岐命令であっても、分岐方向予測器がtakenだと言えば分岐予測成功になります。 BTBが欠如しているため、こういうことになるようです。
x86トレースにおける問題点
pop命令のレイテンシが長すぎる
pop
命令はRSP
レジスタとなんらかのメモリをソースとし、RSP
レジスタと他のレジスタをデスティネーションとする命令です。RSP
レジスタの値は、RSP
レジスタの値足す8になるのですが、見た目上、メモリから読み出した内容に依存してRSP
が決まるようにも見えるため、そのような依存の連鎖でシミュレーションされています。シミュレーション対象プログラムの実行速度はほとんどこれに支配されています。DPC3の性能向上値はこの点で怪しいです。
A64トレースにおける問題点
命令のスケジューリングがおかしい2
命令間の依存関係を推定する部分にヒューリスティクスが導入されましたが、A64トレースでは完全におかしくなります。
条件分岐命令が即実行される
条件分岐命令のソースレジスタがEIP
レジスタだけになってしまっているため、本当はほかのレジスタに依存しているであろう条件命令が即実行されてしまいます。これはシミュレーション対象プログラムを不当に高速化しています。IPC1の性能向上値はこの点で怪しいです。