次に、以下のようにALUのリソースを一気に使い切るようなコードを見てみよう。これはDispatcherがC.ADDIを8命令フルにDispatchするがALUの数が足りず、すべての命令を発行することができない場合にFetcherがどのようにリロードするのかを観察する。
000000008000322e <simple_add>: 8000322e: 0505 addi a0,a0,1 80003230: 0589 addi a1,a1,2 80003232: 060d addi a2,a2,3 80003234: 0691 addi a3,a3,4 80003236: 0715 addi a4,a4,5 80003238: 0799 addi a5,a5,6 8000323a: 081d addi a6,a6,7 8000323c: 08a1 addi a7,a7,8 8000323e: 0925 addi s2,s2,9 80003240: 09a9 addi s3,s3,10 80003242: 0a2d addi s4,s4,11 80003244: 0ab1 addi s5,s5,12 80003246: 0b35 addi s6,s6,13 80003248: 0bb9 addi s7,s7,14 8000324a: 0c3d addi s8,s8,15 8000324c: 0cc1 addi s9,s9,16 8000324e: 0d45 addi s10,s10,17 80003250: 0dc9 addi s11,s11,18 80003252: 0e4d addi t3,t3,19 80003254: 854a mv a0,s2 80003256: 8082 ret
この場合、どうもDispatcherの幅はALUの最大幅と一緒になるようだ(つまり5)。従ってC.ADDI
命令が最大幅でひたすら発行され続けることになる。
上記はGigaBoomConfigの様子だが、MegaBoomConfigの場合はどうなるのか。MegaBoomConfigの場合はDispatch幅が4なのでそれだけの幅いっぱいで発行されるのだろうか。
その通りだった。発行幅4で最大幅で発行され続ける。
これはALUの個数が5つ(MegaBoomConfigの場合は4つ)あるのでこれで良いが、そうでない、例えば乗算命令などはどうなるのだろうか?以下のようなプログラムを作ってDispatchの様子を確かめてみたいと思う。以下のようなプログラムを用意した。
0000000080003256 <simple_mul>: 80003256: 02a50533 mul a0,a0,a0 8000325a: 02b585b3 mul a1,a1,a1 8000325e: 02c60633 mul a2,a2,a2 80003262: 02d686b3 mul a3,a3,a3 80003266: 02e70733 mul a4,a4,a4 8000326a: 02f787b3 mul a5,a5,a5 8000326e: 03080833 mul a6,a6,a6 80003272: 031888b3 mul a7,a7,a7 80003276: 03290933 mul s2,s2,s2 8000327a: 033989b3 mul s3,s3,s3 8000327e: 034a0a33 mul s4,s4,s4 80003282: 035a8ab3 mul s5,s5,s5 80003286: 036b0b33 mul s6,s6,s6 8000328a: 037b8bb3 mul s7,s7,s7 8000328e: 038c0c33 mul s8,s8,s8 80003292: 039c8cb3 mul s9,s9,s9 80003296: 03ad0d33 mul s10,s10,s10 8000329a: 03bd8db3 mul s11,s11,s11 8000329e: 854a mv a0,s2 800032a0: 8082 ret
波形を観測していると、おや、最大Dispatch幅で発行され続けている。これはいったいどういう仕組みだ?
ログ上では、パイプライン上に1サイクルずつ依存しない乗算命令が完了していることが分かる。
3832 3 0x0000000080003256 mul a0, a0, a0 x10 0x0000000000000000 3833 3 0x000000008000325a mul a1, a1, a1 x11 0x0000000000000001 3834 3 0x000000008000325e mul a2, a2, a2 x12 0x400035400b139000 3835 3 0x0000000080003262 mul a3, a3, a3 x13 0x400232c4d50f9000 3836 3 0x0000000080003266 mul a4, a4, a4 x14 0x0000000000000000 3837 3 0x000000008000326a mul a5, a5, a5 x15 0x0000000000000000 3838 3 0x000000008000326e mul a6, a6, a6 x16 0x0000000000000000 3839 3 0x0000000080003272 mul a7, a7, a7 x17 0x0000000000000000 3840 3 0x0000000080003276 mul s2, s2, s2 x18 0x0000000000000000 3841 3 0x000000008000327a mul s3, s3, s3 x19 0x0000000000000000 3842 3 0x000000008000327e mul s4, s4, s4 x20 0x0000000000000000 3843 3 0x0000000080003282 mul s5, s5, s5 x21 0x0000000000000000 3844 3 0x0000000080003286 mul s6, s6, s6 x22 0x0000000000000000 3845 3 0x000000008000328a mul s7, s7, s7 x23 0x0000000000000000 3846 3 0x000000008000328e mul s8, s8, s8 x24 0x0000000000000000 3847 3 0x0000000080003292 mul s9, s9, s9 x25 0x0000000000000000 3848 3 0x0000000080003296 mul s10, s10, s10 x26 0x0000000000000000 3849 3 0x000000008000329a mul s11, s11, s11 x27 0x0000000000000000
どういう仕組みになっているのか見ているが、どうもint_issue_unit
がその辺の管理をしているように見える。ここで発行制御を行っている訳か。ではこのint_issue_init
があふれてしまった場合はどうするのだろう?パラメータを変えて別のRTLを生成して観察してみようか。