RISC-VプロセッサHiFive1でMNISTを実行させている。現状の問題点としては、いろいろなところが遅いことだ。 予想よりも性能が出ない。いろいろ試行した結果、やはり問題としては学習データがCPUに対して遠いところにある事だろう。 つまり、固定値の学習データをフラッシュメモリの上に置いており、そこにデータを毎回取りに行っている。 行列式の計算なので、縦方向の計算になり、あらかじめ局所的な部分をあらかじめL1キャッシュにロードしておくのも難しい。 何とかして少しでも高速化できないだろうか。
固定値の中でも、小さなものはL1に置きなおすことができるかもしれない。 現状、固定値としてフラッシュメモリに置いているのは、
- 入力データ (28x28バイトx100個分)
- MNIST学習済みデータ1. (28x28x50x4バイト : 50はHidden Layerのサイズ)
- MNIST学習済みデータ2. (50x4バイト : 50はHidden Layerのサイズ)
- MNIST学習済みデータ3. (50x10x4バイト : 10は出力層のサイズ)
- MNIST学習済みデータ4. (10x4バイト : 10は出力層のサイズ)
ということで、とりあえず一番大きいのは最初の学習済みデータな訳だが、これを全部L1キャッシュに入れるのはちょっと無理だ。 それ以外のものなら入るかもしれない。プログラムを実行する前に、これらの学習済みデータをL1キャッシュにコピーしてみよう。
もともとのフラッシュメモリに格納されたデータは、以下のようにして参照している。
extern char _binary_wb0_bin_start[]; extern char _binary_wb0_bin_end[]; extern char _binary_wb1_bin_start[]; extern char _binary_wb1_bin_end[]; extern char _binary_wh0_bin_start[]; extern char _binary_wh0_bin_end[]; extern char _binary_wh1_bin_start[]; extern char _binary_wh1_bin_end[]; const fix16_t *wh0 = (fix16_t *)_binary_wh0_bin_start; // [INPUTNO * HIDDENNO]; const fix16_t *wb0 = (fix16_t *)_binary_wb0_bin_start; // [HIDDENNO]; const fix16_t *wh1 = (fix16_t *)_binary_wh1_bin_start; // [HIDDENNO * OUTPUTNO]; const fix16_t *wb1 = (fix16_t *)_binary_wb1_bin_start; // [OUTPUTNO];
最初のwh0
は非常に大きいので、さすがにこれはL1に格納できない。それ以外のものをコピーする。
const fix16_t *wh0 = (fix16_t *)_binary_wh0_bin_start; // [INPUTNO * HIDDENNO]; const fix16_t *c_wb0 = (fix16_t *)_binary_wb0_bin_start; // [HIDDENNO]; const fix16_t *c_wh1 = (fix16_t *)_binary_wh1_bin_start; // [HIDDENNO * OUTPUTNO]; const fix16_t *c_wb1 = (fix16_t *)_binary_wb1_bin_start; // [OUTPUTNO]; int main () { int i; // for (i = 0; i < INPUTNO * HIDDENNO; i++) wh0[i] = c_wh0[i]; for (i = 0; i < HIDDENNO; i++) wb0[i] = c_wb0[i]; for (i = 0; i < HIDDENNO * OUTPUTNO; i++) wh1[i] = c_wh1[i]; for (i = 0; i < OUTPUTNO; i++) wb1[i] = c_wb1[i];
フラッシュメモリのデータへのポインタをc_wb0
, c_wh1,
c_wb1として、L1のデータ格納場所
wb0, wh1, wb1`へコピーする。これでどれくらい速くなるか。
- 高速化処置前 : 4960983060 サイクル
- 高速化処理後 : 4893267026 サイクル
割合にして1.5%程度だ。あんまり劇的な効果にはなっていないなあ。やはり一番大きなデータを格納できていないことが原因か。 まあ、これ以上HiFive1で巨大が画像を処理させるのはちょっと無理かな。