1. はじめに
こちらの記事「FPGAオンボードメモリのデバッグ ~テストパターン生成/表示画面のキャプチャ~」を書くために、MATLABで固定小数点データを行なったら、すごく遅かったので、そのソリューションをこちらの記事「MATLABの固定小数点演算って時間かかりすぎじゃね?」に書きました。
ただ、ソリューションであるfiaccelは、関数化とコンパイルしてから実行する必要があり、ひと手間かかって面倒でした。
コードを書いたらすぐに実行できる方法を模索したところ、Simulinkモデルで処理することで高速に実行できることがわかりましたので、やり方を説明したいと思います。
2. 固定小数点演算の内容
元のMATALBコードは、 [1024x768] 画素の画像データを、FPGAボードのDDRメモリに書き込む 4byte のデータに変換する内容です。
固定小数点演算は、8bitデータを連結して32bitにするだけの至って簡単な処理ですが、このコードを実行するのにMATLABだとなんと70分もかかってしまいます。
以下のコードで時間がかかっているのは、殆どがforループ内の固定小数点演算の部分です。
imageSize = [768, 1024]; % v, h
nt8 = numerictype(0, 8, 0);
nt32 = numerictype(0, 32, 0);
inputImageP = imresize(imread('peppers.png'), imageSize);
figure, imshow(inputImageP), shg
% RGB => BGR
inputImagePP = inputImageP(:,:,[3 2 1]);
serialImageP = reshape(permute(inputImagePP, [3, 2, 1]), [prod(imageSize)*3, 1, 1]);
writeDataP = fi(zeros(1, prod(imageSize)*3/4), nt32);
for n = 0:length(serialImageP)/4-1
writeDataP(n+1) = fi(bitconcat(...
fi(serialImageP(n*4+4), nt8),...
fi(serialImageP(n*4+3), nt8),...
fi(serialImageP(n*4+2), nt8), ...
fi(serialImageP(n*4+1), nt8)), nt32);
end
3. MATLABコードをSimulinkにコピペ
MATLABコードをSimulink上で実行するにはMATLAB Functionブロックを使用します。
このブロックを開くとMATLABエディターが開くので、そこに上述のコードをコピペします。
Simulinkモデルの最上位階層は、MATLAB FunctionブロックをTo Workspaceブロックに接続しただけのシンプルな構成です。このTo Workspaceブロックは、SimulinkのシミュレーションデータをMATLABのワークスペースにエクスポートするためのブロックです。
処理をするのは1フレームのみなので、シミュレーション終了時間は [0] に設定しています。(Simulinkは時間 0 で最初の処理が実行され、以下シミュレーションステップごとの時間で処理が実行されます。)
4. Simulinkモデルの実行時間
以下のコマンドでSimulinkモデルを実行して時間測定しました。
>> tic, sim(gcs), toc
経過時間は 1.174739 秒です。
MATLABで70分かかった処理が、Simulinkではfiaccelよりは遅いものの、十分に実用的な時間で処理が完了しています。
上記のSimulinkモデルで実行している内容が、以下の理由から少し大きめになっています。
- fiaccelコマンドで変換したコードよりも処理が多い
- fiaccelは予めコンパイルしてから、実行時間のみ測定しているが、Simulinkモデルはコンパイル時間も含まれる
しかし、fiaccel:0.046277秒と、Simulink 1.174739秒というのは、人間が認識する時間として実用上大差ないため、使い勝手の良いほうを使えば良いと思います。
5. 結論
MATLABで時間のかかる固定小数点演算は、Simulink上でMATLAB Functionブロックを使うと、プリコンパイル実行されるため高速化できる。
終わり