シリアルFlashメモリ(2) 
   ビット交換の高速化


 「シリアルFlashメモリ(1) ReadID実行でビット交換」のページで、H8/36078を使ったビット交換を試しました。しかし、 余りにも遅いので驚きました。
 ここでは、H8/36078のソフトウエアの書き換えだけで出来るビット交換機能の高速化にチャレンジします。

●「ビット交換」ソフトを配列方式からポインタ方式に

 「シリアルFlashメモリ(1) ReadID実行でビット交換」のページのビット交換は、ビット位置を逆にしたテーブルを配列方式で検索していました。この配列方式による「ビット交換」時間は、208uS掛かり非常に驚きました。
 時間が掛かる原因の手がかりを掴むため、HEWのC言語とアッセンブル言語の混合モードで表示させましが、何やら難しい事をしてるな、程度しか理解できませんでした。

 一般的に、「配列方式は時間が掛かる」「配列方式よりポインタ方式の方が速い」とものの本書かれていたので、変換テーブルはそのままで検索をポインタ方式にしました。しかし、214uSとより遅くなりました。再び混合モードで表示させたら、アッセンブル言語の内容はほとんど同じで、ポインタのアドレスに命令が増えています。テーブルを構成するアッセンブル言語のサブルーチンコールも同じです。
 推測するに、テーブルを構成するアッセンブル言語のルーチンに時間が掛かっていそうです。


●それなら どうする

 変換テーブルによる一括変換方式時間がかかるなら、個別変換方式ではと思いビット毎に変換しました。
 




 変換する8ビットのデータと、
変換後に入れる8ビットのレジスタを用意して。

 変換するデータのLSBから1ビット取り出し、
変換後のレジスタのLSBに格納します。

 そして、変換するデータを1ビット右シフト、
変換後のレジスタを1ビット左シフトします。


 これを8回すると、ビット交換できます。


 この方式を、BitSwapShift()関数としてまとめて
実行すると、大幅な時間短縮出来ました。
 実行時間は、41uSになりました。







●それから どうする

 もっと速くならないか? 「這えば起て、起てば歩めの親心」を思い出しながら考えました。

 BitSwapShift()関数は、変換するデータと、変換後のレジスタの処理を別々にしています。
 一つの処理にまとめられないか?

 変換するデータはそのままで、変換後のレジスタの位置を調整する。
 すなわち、変換するデータから抜くビット位置に、変換後のレジスタのビット挿入位置に合わせます。

 変換後のレジスタを16ビットにして、1ビット処理毎に2ビット左シフトしました。




この方式を、BitSwapModShift()関数としてまとめて実行すると、より時間短縮が出来ました。
 実行時間は、31uSになりました。





●「ビット交換」処理時間の整理

 「ビット交換」処理時間を整理します。

 ・「ビット交換」処理が無い場合  : 14uS
 ・テーブル方式の「ビット交換」  :208uS   純増加 :194uS
 ・シフト方式の「ビット交換」   : 41uS   純増加 : 27uS
 ・変形シフト方式の「ビット交換」 : 31uS   純増加 : 17uS

 変形シフト方式の「ビット交換」の純増加は、17uSです。
 1Mバイト変換すると17秒です、操作する人は我慢出来る範囲かな?


●大事な事を考え落としてないかな!

 ここまで書いて、何か考え落としてる様な気になってきました。

 「変換テーブル方式」で 「推測するに、テーブルを構成するアッセンブル言語のルーチンに時間が掛かっていそうです。」と書いていました。
 「テーブルを構成するのに時間が掛かっている」なら、毎回繰り返さなければイイのでは。
 ルーチンの外に出したら。ローカル変数で無くグローバル変数にしては。
 と頭の中で叫んでいます。

 今は、194uSの純増加が17uSになったので、叫んでいる一方の脳を落ち着かせています。
 毎回繰り返さなければイイ方式は、別の機会に試す事とします。


ホームへ戻る