Super Sylphide 進捗状況(10) -- C6700用行列ライブラリ 再び

オートパイロットシステム Super Sylphideの開発をしている過程で、以前、TIのDSP TMS320C6713用のC++行列ライブラリを作ったよ、という記事を書きました。しかし最近になって検証をまじめにしたところ、メモリが漏れていたり(汗)、条件によっては無限ループにハマってしまったり(汗)、と大変な状況であることが判明したので、バグフィックスをしました。

現時点での最新版をここにおいておきます。(更新履歴は記事の一番後ろにあります)

修正点は以下2つです。

まず一点は、メモリが漏れていました。すいません。参照カウンタという仕組みを利用して行列成分を保存する領域の管理をしているのですが、行列成分(ソース内:Array2D_Dense::m_Values)自体は管理ができていたものの、それのお目付け役である参照カウンタ(ソース内:Array2D_Dense::ref)のdeleteをし忘れていました。

もう一点は行列積を高速化するためにTI純正のライブラリ TMS320C67x DSP Library (dsp67x.lib)のDSPF_dp_mat_mul / DSPF_sp_mat_mul 関数を使っていたのですが、行数あるいは列数が奇数のときに無限ループに落ち込んで呼び出し元に復帰しない現象が確認されました。
これはドキュメントに、行数あるいは列数が奇数のときには偶数分だけメモリを読むので注意しなさい、ということが書いてあるのでずか、その解釈を誤っていたことが原因でした。ライブラリの元ソース(dsp67x.src)を確認してみると行、列成分は偶数分メモリが確保されていることが高速化のために前提となっており、2 x 2の小行列単位で処理を行うようになっていました。
そこで行列をクラス階層的にラップして、例えば7 x 7といった奇数個成分の行列でもメモリは8 x 8分確保する、という構造にしました。これにはC++の機能である仮想関数やテンプレート特殊化が大活躍しています。
ちなみにですがdsp67x.libを使うと、例えば10 x 10の行列積が2490サイクル(200MHz動作時だと約1.3 usec)、とかなり速いのでお勧めです。

今後のこのライブラリの予定ですが、ある行列と転置行列の積が若干オーバヘッド気味なことをしている(転置行列の成分をディープコピーして並べ替えたあと、積算)なので、アセンブラでDSPF_dp_mat_mul / DSPF_sp_mat_mul 関数に似た専用関数を作ろうかと考えています。また参照カウンタ自体のメモリをnewで確保する(アロケータの性質にもよるが、小さい領域をヒープから取るのはあまり得策でないよう)のが微妙なので、placement newあたりでDSP/BIOSのBUFモジュールと組み合わせたカスタムアロケータから、メモリを確保するようにしようかと考えています。

※その後、GPSが使用不能の場合でも時刻を保持するためのTime Keeperモジュールを作成しました。

※※2009/05/30 コードを更新しました。転置行列との積などが高速化されるようにしました。

September 29, 2007 10:17 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク

コメント

コメントする