前回の記事で、Rocket-Chip で任意のプログラムを実行できるような環境が構築できた。 これでRocket-Chipの体力測定ができそうだ。
まずは各命令のレイテンシ・スループットを測定するのがよさそうだ。 命令の実行レイテンシやスループットは、一般的には、同じ命令を何度も繰り返して実行して測定する。
図. Rocket Coreのパイプライン (https://aspire.eecs.berkeley.edu/wp/wp-content/uploads/2016/04/Tech-Report-The-Rocket-Chip-Generator-Beamer.pdf より抜粋)。
以下のプログラムは、出力レジスタの依存関係が存在しないので、命令依存関係がなく、スループットが測定できる。
program/benchmark/inst_add/inst_add.c
... for (i = 0; i < 32; i++) { asm volatile ("add %0,%1,%2" :"=r"(out0) :"r"(in0_0),"r"(in0_1) : ); asm volatile ("add %0,%1,%2" :"=r"(out1) :"r"(in1_0),"r"(in1_1) : ); asm volatile ("add %0,%1,%2" :"=r"(out2) :"r"(in2_0),"r"(in2_1) : ); asm volatile ("add %0,%1,%2" :"=r"(out3) :"r"(in3_0),"r"(in3_1) : ); asm volatile ("add %0,%1,%2" ...
一方で以下のプログラムは、出力レジスタを次の命令レジスタで使うので、1命令に必要なレイテンシを測定できる。
RISC-V add 命令のスループット
330 - 337がサイクル数。1サイクル毎に実行されていることが分かる。IPC=1.0だ。
C0: 330 [1] pc=[00800000a8] W[r25=00000000cb5f139c][1] R[r 9=000000004f7a652e] R[r 8=000000007be4ae6e] inst=[00848cb3] add s9, s1, s0 C0: 331 [1] pc=[00800000ac] W[r24=0000000063bb12ae][1] R[r 7=000000005e9aaa1d] R[r 5=0000000005206891] inst=[00538c33] add s8, t2, t0 C0: 332 [1] pc=[00800000b0] W[r23=000000014ad97382][1] R[r31=000000004d1f56e1] R[r17=00000000fdba1ca1] inst=[011f8bb3] add s7, t6, a7 C0: 333 [1] pc=[00800000b4] W[r22=00000000ac561dbb][1] R[r16=00000000845cb9cb] R[r30=0000000027f963f0] inst=[01e80b33] add s6, a6, t5 C0: 334 [1] pc=[00800000b8] W[r21=0000000146687fa8][1] R[r10=0000000083f85a2f] R[r11=00000000c2702579] inst=[00b50ab3] add s5, a0, a1 C0: 335 [1] pc=[00800000bc] W[r20=000000007b5a2ebe][1] R[r29=0000000046081d0a] R[r28=00000000355211b4] inst=[01ce8a33] add s4, t4, t3 C0: 336 [1] pc=[00800000c0] W[r19=0000000155d5e712][1] R[r12=00000000fd6878f7] R[r 6=00000000586d6e1b] inst=[006609b3] add s3, a2, t1 C0: 337 [1] pc=[00800000c4] W[r18=000000014d25a196][1] R[r13=00000000b059fbf5] R[r14=000000009ccba5a1] inst=[00e68933] add s2, a3, a4
RISC-V add 命令レイテンシ
326 - 333 がサイクル数。1サイクル毎にこちらも実行されていることが分かる。レイテンシも1.0だ。スループットとレイテンシがどちらも1.0なので少し面白くない。
C0: 326 [1] pc=[008000005c] W[r17=00000000cb5f139c][1] R[r 9=000000004f7a652e] R[r 8=000000007be4ae6e] inst=[008488b3] add a7, s1, s0 C0: 327 [1] pc=[0080000060] W[r16=0000000129f9bdb9][1] R[r 7=000000005e9aaa1d] R[r17=00000000cb5f139c] inst=[01138833] add a6, t2, a7 C0: 328 [1] pc=[0080000064] W[r10=000000017719149a][1] R[r 5=000000004d1f56e1] R[r16=0000000129f9bdb9] inst=[01028533] add a0, t0, a6 C0: 329 [1] pc=[0080000068] W[r11=00000001fb75ce65][1] R[r30=00000000845cb9cb] R[r10=000000017719149a] inst=[00af05b3] add a1, t5, a0 C0: 330 [1] pc=[008000006c] W[r12=000000027f6e2894][1] R[r29=0000000083f85a2f] R[r11=00000001fb75ce65] inst=[00be8633] add a2, t4, a1 C0: 331 [1] pc=[0080000070] W[r13=00000002c576459e][1] R[r31=0000000046081d0a] R[r12=000000027f6e2894] inst=[00cf86b3] add a3, t6, a2 C0: 332 [1] pc=[0080000074] W[r14=00000003c2debe95][1] R[r28=00000000fd6878f7] R[r13=00000002c576459e] inst=[00de0733] add a4, t3, a3 C0: 333 [1] pc=[0080000078] W[r18=000000047338ba8a][1] R[r 6=00000000b059fbf5] R[r14=00000003c2debe95] inst=[00e30933] add s2, t1, a4
もう少しいろんな命令を実行してみよう。FPUとか面白そうだ。
2018/03/07追記。整数乗算命令についても実験してみた。発行レートは7サイクルに1回... IPC=0.142だって!? そんなことあるかなあ。パイプライン化されていないのかも。
C0: 1481 [1] pc=[008000008e] W[r 0=00000000cb5f139c][1] R[r17=000000004f7a652e] R[r16=000000007be4ae6e] inst=[03088b33] mul s6, a7, a6 C0: 1488 [1] pc=[0080000092] W[r 0=0000000063bb12ae][1] R[r10=000000005e9aaa1d] R[r11=0000000005206891] inst=[02b50bb3] mul s7, a0, a1 C0: 1495 [1] pc=[0080000096] W[r 0=000000014ad97382][1] R[r12=000000004d1f56e1] R[r14=00000000fdba1ca1] inst=[02e60c33] mul s8, a2, a4 C0: 1502 [1] pc=[008000009a] W[r 0=00000000ac561dbb][1] R[r15=00000000845cb9cb] R[r13=0000000027f963f0] inst=[02d78cb3] mul s9, a5, a3 C0: 1503 [1] pc=[008000009e] W[r 6=0000000000000014][1] R[r 6=0000000000000015] R[r31=0000000027f963f3] inst=[0000337d] addiw t1, t1, -1 C0: 1504 [1] pc=[00800000a0] W[r 0=0000000000000000][0] R[r 6=0000000000000014] R[r 0=0000000000000000] inst=[fa031fe3] bnez t1, pc - 66 C0: 1509 [1] pc=[008000005e] W[r 0=00000000cb5f139c][1] R[r17=000000004f7a652e] R[r16=000000007be4ae6e] inst=[030884b3] mul s1, a7, a6 C0: 1516 [1] pc=[0080000062] W[r 0=0000000063bb12ae][1] R[r10=000000005e9aaa1d] R[r11=0000000005206891] inst=[02b50433] mul s0, a0, a1 C0: 1523 [1] pc=[0080000066] W[r 0=000000014ad97382][1] R[r12=000000004d1f56e1] R[r14=00000000fdba1ca1] inst=[02e603b3] mul t2, a2, a4 C0: 1530 [1] pc=[008000006a] W[r 0=00000000ac561dbb][1] R[r15=00000000845cb9cb] R[r13=0000000027f963f0] inst=[02d782b3] mul t0, a5, a3 C0: 1537 [1] pc=[008000006e] W[r 0=00000000cb5f139c][1] R[r17=000000004f7a652e] R[r16=000000007be4ae6e] inst=[03088fb3] mul t6, a7, a6 C0: 1544 [1] pc=[0080000072] W[r 0=0000000063bb12ae][1] R[r10=000000005e9aaa1d] R[r11=0000000005206891] inst=[02b50f33] mul t5, a0, a1 C0: 1551 [1] pc=[0080000076] W[r 0=000000014ad97382][1] R[r12=000000004d1f56e1] R[r14=00000000fdba1ca1] inst=[02e60eb3] mul t4, a2, a4 C0: 1558 [1] pc=[008000007a] W[r 0=00000000ac561dbb][1] R[r15=00000000845cb9cb] R[r13=0000000027f963f0] inst=[02d78e33] mul t3, a5, a3 C0: 1565 [1] pc=[008000007e] W[r 0=00000000cb5f139c][1] R[r17=000000004f7a652e] R[r16=000000007be4ae6e] inst=[03088933] mul s2, a7, a6 C0: 1572 [1] pc=[0080000082] W[r 0=0000000063bb12ae][1] R[r10=000000005e9aaa1d] R[r11=0000000005206891] inst=[02b509b3] mul s3, a0, a1 C0: 1579 [1] pc=[0080000086] W[r 0=000000014ad97382][1] R[r12=000000004d1f56e1] R[r14=00000000fdba1ca1] inst=[02e60a33] mul s4, a2, a4 C0: 1586 [1] pc=[008000008a] W[r 0=00000000ac561dbb][1] R[r15=00000000845cb9cb] R[r13=0000000027f963f0] inst=[02d78ab3] mul s5, a5, a3 C0: 1593 [1] pc=[008000008e] W[r 0=00000000cb5f139c][1] R[r17=000000004f7a652e] R[r16=000000007be4ae6e] inst=[03088b33] mul s6, a7, a6 C0: 1600 [1] pc=[0080000092] W[r 0=0000000063bb12ae][1] R[r10=000000005e9aaa1d] R[r11=0000000005206891] inst=[02b50bb3] mul s7, a0, a1 C0: 1607 [1] pc=[0080000096] W[r 0=000000014ad97382][1] R[r12=000000004d1f56e1] R[r14=00000000fdba1ca1] inst=[02e60c33] mul s8, a2, a4
2018/03/10 追記。タイムアウトまで実行するのは時間がかかりすぎるのでベンチマークが終了するとシミュレーションも終了するようにする。
計測後に以下のコードを実行するようにする。 これにより、デバッグ領域にメモリアクセスが入り、これを検知するとRTLシミュレーションを終了する。
void finish () __attribute__((section(".text"))); void run_bench () {benchmark (); benchmark(); finish(); } void finish () { asm volatile ("csrr s0, mhartid"); asm volatile ("sw s0, 264(zero)"); asm volatile ("csrr s0, dscratch"); asm volatile ("dret"); }
- tp_freechips_rocketchip.sv
always_ff @ (posedge clock) begin if (tb.duv.ExampleRocketSystem.debug_1.auto_dmInner_dmInner_tl_in_a_valid && tb.duv.ExampleRocketSystem.debug_1.auto_dmInner_dmInner_tl_in_a_ready && tb.duv.ExampleRocketSystem.debug_1.auto_dmInner_dmInner_tl_in_a_bits_address == 32'h108) begin $fwrite (32'h80000002,"ExapmleRocketSystem Debug Asserted. Finished.\n"); $finish; end end