早速の訂正であります。昨日、RISC-V搭載マイコンGD32VF103のメモリアクセス思ったより遅いじゃん、などとディスってしまいましたが、大間違いでした。申し訳ありません。私のバグです。9サイクルと書いていたところ、実際は2サイクルです。
※「ぐだぐだ低レベルプログラミング」投稿順indexはこちら
昨日は、1本投稿したらちょっと一杯とか考えており、大間抜けでした。すみません。昨日投稿の
ぐだぐだ低レベルプログラミング(23) GD32VF103, メモリアクセスを測る
の結果、なんか非常に遅いんでないかい、と引っかかるものがありつつ、そのまま投稿してしまいました。本日、毎週恒例の高齢の母親の介護の付き添いで、病院の待合室でボーッと座っていて気付きました。
アセンブラに渡す引数(バイト数)、C配列の要素数で書いていた
大馬鹿者です。アセンブラ書いたのも私、Cのコードを書いたのも私、気付かないまま実行していたことがおかしい。具体的にはここです。
// 昨日の駄目なコード work0 = cycRdMem(sramArray, 1, 16, 16); // 本日修正した「意図」どおりのコード work0 = cycRdMem(sramArray, 4, 64, 16);
つまり、計測用の関数に渡す第2、第3引数が自分で想定した意図とは違っていました。そのうち、「サイクル数の遅延」を直接引き起こしていたのは、第2引数の方です。何を勘違いしたか、Cの配列の要素番号 sramArray[1] みたいな添え字の感覚で1などと書いていました。ここはアセンブラ側の引数としてはバイトオフセットです。よって
昨日の結果は、ミスアライメントのアドレスへのアクセスの結果
であります。ここでRISC-Vの偉大なところなのですが、
- RISC-Vはミスアライメントのメモリアクセスを許す
のであります。RISCにしては珍しい仕様かもしれません。かの「RISC-V原典」にはその理由も書いてあるので、気になる人はそちらをご覧ください。なお、「絶対に」そういう実装でなければならないというわけではなく、実装面倒なときは、ミスアライメントアクセスにトラップかけてソフトで対処してもいいらしいです。これも「RISC-V原典」の後ろの方に書いてあります。
普通のRISCならば、昨日のようなコードは実行時エラーで即バレますが、偉大なRISC-Vはなんとか実行してくれた結果、
- ミスアライメントのワード(4バイト)アクセスを頑張った結果の9サイクル
でした。トラップかけていたらとても9サイクルでは終わらない筈なので、GD32VF103搭載のRISC-Vのコア “Bumblebee” はミスアライメント・アクセスを行えるハードウエアを搭載していることが図らずも?明らかとなりました。許すけれども当然そのペナルティは大きいです。その結果の9サイクル。
先ほど、再測定してみたところ、本日の結論は、
- SRAMでもFLASHでもメモリリード(アライメント)は2サイクル
でした。
SRAMとしては普通だけれど、FLASH相手の2サイクルは上々じゃないでしょうかね。謹んで訂正させていただきます。