11 |
RISC-Vの調査 (3) |
前々稿の記事において、シミュレーションモデルが生成できましたが、これを実行させてみます。
テストプログラムは、add命令単体テストで、
80000000 <_start>: 80000000: 04c0006f j 8000004c <reset_vector> 8000004c <reset_vector>: 8000004c: f1402573 csrr a0,mhartid 80000050: 00051063 bnez a0,80000050 <reset_vector+0x4> 80000054: 00000297 auipc t0,0x0 80000058: 01028293 addi t0,t0,16 # 80000064 <reset_vector+0x18> 8000005c: 30529073 csrw mtvec,t0 80000060: 18005073 csrwi satp,0 : 80000100 <test_2>: 80000100: 00000093 li ra,0 80000104: 00000113 li sp,0 80000108: 00208f33 add t5,ra,sp 8000010c: 00000e93 li t4,0 80000110: 00200193 li gp,2 80000114: 4ddf1663 bne t5,t4,800005e0 <fail> 80000118 <test_3>: 80000118: 00100093 li ra,1 8000011c: 00100113 li sp,1 80000120: 00208f33 add t5,ra,sp 80000124: 00200e93 li t4,2 80000128: 00300193 li gp,3 8000012c: 4bdf1a63 bne t5,t4,800005e0 <fail> :
のように構成されています。Bsimによるシミュレーションは、+v1で命令トレースが、+v2でパイプラインステージの内容を表示させるようになっています。+v2で実行させた結果をgrepにより計数してみると、表274.1のようになりました。パイプラインの各ステージの出力ステータスの意味は、以下のとおりです。
- EMPTY --- 入力が来ないためアイドルとなっている
- BUSY --- 入力があるが、処理中で出力がレディではない
- PIPE --- 入力があり、パイプラインは正常な出力を行っている
- NONPIPE --- 入力があり、出力は例外的な場合(トラップ等)
状態 | StageF | StageD | Stage1 | Stage2 | Stage3 |
---|---|---|---|---|---|
BUSY | 1,118 | 0 | 23 | 26 | 0 |
EMPTY | 22 | 1,094 | 959 | 1,373 | 1,409 |
PIPE処理 | 743 | 789 | 901 | 484 | 474 |
合計 | 1,883 |
- 試験命令数は473命令だったので、CPI(Cycles Per Instruction)は3.98となりました。命令キャッシュミスのためにかなり大きく(悪く)なっています。
- マシンサイクル1,883サイクルのうち、実際に処理しているのは半分くらいであり、主なパイプラインストールは命令キャッシュによるものだと考えられます。
- StageFがBUSYの分だけStageD以降がEMPTYとなり、空いています。すなわち約1,100サイクルがパイプラインバブルとなっています。
- Stage1に対してStage2のPIPE処理が半分なのは、ロードストア命令が半分(レジスタとロードストアが1:1)くらいだからかもしれません。
- StageDに対してStage1のPIPE処理が増加しているのは、マルチサイクル命令のためかもしれません。
これだけ見るとかなり効率が悪そうですが、対象がテストプログラムでループが無いため、基本的にキャッシュミスが頻発します。一般のアプリケーションのようにループがあれば、ずっと効率が向上するはずです。