自作RISC-Vプロセッサは16バイト単位で命令をフェッチしてくる。つまり分岐などで新しい場所に命令フェッチを発生した時も、16バイトアラインで命令をフェッチする。
このとき、分岐先や関数の先頭が16バイトに乗っていると効率的だ。16バイトアラインの乗っていないとその分命令フェッチラインを損していることになる。
このとき、分岐先の命令のバイトアラインを調整するために、RISC-VのGCCには以下のコンパイルオプションが乗っている。
-falign-functions=16 -falign-jumps=16 -falign-labels=16 -falign-loops=16
これらにより、ジャンプ先の命令が16バイトアラインに制限される。
例えば、分岐先を調整するために以下のようにわざとnopが挿入される。
80001050: 0088de93 srli t4,a7,0x8 80001054: 01de6f33 or t5,t3,t4 80001058: 01e59023 sh t5,0(a1) 8000105c: 00259583 lh a1,2(a1) 80001060: 40b50533 sub a0,a0,a1 80001064: 00008067 ret 80001068: 00000013 nop // この2つのnopにより、次の関数の場所が調整される。 8000106c: 00000013 nop // この2つのnopにより、次の関数の場所が調整される。 80001070 <core_list_mergesort.constprop.2>: 80001070: 00100f93 li t6,1 80001074: 000f8393 mv t2,t6 80001078: 26050c63 beqz a0,800012f0 <core_list_mergesort.constprop.2+0x280> 8000107c: 00000013 nop 80001080: 00000f13 li t5,0 80001084: 00000693 li a3,0 80001088: 00000293 li t0,0 8000108c: 00000013 nop 80001090: 00052783 lw a5,0(a0)
この調整を行って、昨日と同様にCoremarkの性能を測定した。
Inst Bufferサイズ | サイクル数 | 比率 | サイクル数 | 比率 |
---|---|---|---|---|
通常Coremark | アライン調整Coremark | |||
2 | 406395 | 1.00 | 360167 | 0.89 |
4 | 371580 | 0.91 | 340276 | 0.84 |
8 | 403437 | 0.99 | 366379 | 0.90 |
16 | 476439 | 1.17 | 429816 | 1.06 |
やはり、命令バッファが4の場合に最大の効果が得られた。命令の位置を調整しただけで、かなりの効果だ。