RISC-V評価ボードのHiFive1は、オンチップのメモリが少なく、L1Dキャッシュが16KBしかない。それ以外のデータにアクセスするためには、外部のフラッシュメモリを利用する必要がある。
これにより、ほとんどすべてのデータはあらかじめフラッシュメモリに格納することになるが、この時のフラッシュメモリのアクセス性能が問題だ。 実際問題、MNISTは画像データとパラメータをフラッシュメモリに配置したことにより、ずいぶんとメモリアクセスに時間がかかり、性能が落ちてしまっている。
一応、HiFive1のフラッシュメモリアクセスにどの程度のレイテンシが必要なのか、定量的なデータを取っておきたい。
メモリのアクセスレイテンシとスループットを計測するためのプログラム
HiFive1のフラッシュメモリにアクセスするためのプログラムを用意した。あらかじめフラッシュメモリにMNISTの画像データを格納しておき、これを取得しに行く。
1回のアクセスに必要なサイクル数がレイテンシ、単位時間毎に何回のメモリアクセスが実行できるかを測定するのがスループットとなる。
レイテンシ測定
以下のようなプログラムを作成して、1回あたりのアクセスサイクルを測定した。 メモリアクセスする前後のサイクルカウントを取得して、引き算する。
for (int i = 0; i < 28*28; i++){ rdmcycle(&before_cycle); rdminstret(&before_instret); volatile char result = p_data[i]; rdmcycle(&after_cycle); rdminstret(&after_instret); if ((i % 100) == 0) { printf ("Start:%ld, Stop:%ld, Cycle=%ld\n", (uint32_t)(before_cycle), (uint32_t)after_cycle, (uint32_t)(after_cycle - before_cycle)); } }
結果、
となった。予想はしていたが、やはり大きい。ちなみに、L1Dキャッシュに配置したデータの場合でも15cycle程度だったので、やはりフラッシュメモリは非常に遅い。
スループット測定
スループットは、データの塊を一気に読み込んで、それで消費したサイクル数を、データ数で除算する。 これにより、単位時間あたりにアクセスできるデータ数が計算でき、それがスループットとなる。
以下のようなプログラムを作成して、スループットを測定した。
rdmcycle(&before_cycle); rdminstret(&before_instret); for (int i = 0; i < 28*28*10; i++){ volatile int result = p_data[i]; } rdmcycle(&after_cycle); rdminstret(&after_instret); printf ("Start:%ld, Stop:%ld, Cycle=%ld\n", (uint32_t)(before_cycle), (uint32_t)after_cycle, (uint32_t)(after_cycle - before_cycle));
動作周波数は、実際のところ260MHz程度で動作しているらしい。28x28x10個のデータ(1データあたり4バイト)にアクセスするのに1220472サイクルかかっている。
core freq at 259450470Hz
従って、スループットは、
となる。やはり、あんまり速くないなあ。RISC-Vチップがもっと世の中に普及するためには、ボードレベルで、メモリ周りの強化をまずは行ってほしい。