フォト
2016年11月
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30      

最近のトラックバック

ロボット部品

無料ブログはココログ

その他ソフトウェア

2014年11月 7日 (金)

プログラムのループと最適化の話

たまには役に立つ話を書きたいと思います.

(使用しているマイコンは,RX210,RX111 です)
 たぶん一般的な話だと思いますが,マイコンなど組み込み関連のプログラムを書く場合,特に意識することが多いです.
プログラムの動作において,一番リソースを使用する部分は主に3つです.
 1.メモリからのデータ読み出し
 2.メモリへのデータ書き出し
 3.ループや条件などの分岐
 メモリの場合,内部メモリなのか外部メモリなのかで変わってきますが,いずれにせよ汎用レジスタへのアクセスにはかないません.
 分岐については,主にアセンブラで言う『ジャンプ』です.
このへんの命令がたくさん入っているプログラム(もっと小さい単位で言えば関数)はとても遅いです.
そこでコンパイラは最適化として何を行うかと言いますと,上記の3項目については以下のようになります.
 1,2.メモリアクセスについて
 関数内で使用される直前にメモリから読み出し,何度も使用されるデータはメモリへ書き戻さず,レジスタに保持します.使用しなくなった後にメモリへ書き出します.例えば・・
int a; ←グローバル宣言
int b;
int c = 1;
void test(void)
{
  b = c + 10;
  a = b + c;
}
というプログラム(内容は無意味ですが)があると,一番遅い動作としては以下の流れになります.
 c 番地から1 をレジスタに読み出す
 1 + 10 を計算してレジスタに入れる
 b 番地に11 を書き出す
 c 番地から1 をレジスタに読み出す
 b 番地から11 をレジスタに読み出す
 11 + 1 を計算してレジスタに入れる
 a 番地に12 を書き出す
これをコンパイラは最適化過程で以下のようにします.
 c 番地から1 をレジスタに読み出す
 1 + 10 を計算してレジスタに入れる
 11 + 1 を計算してレジスタに入れる
 a 番地に12 を書き出す
 b 番地に11 を書き出す
順番はコンパイラによって多少前後しますが,工程が減る仕組みが分かります.

 3.ジャンプについて
 条件分岐がジャンプするのはイメージ通りですが,ループでジャンプというのは少しイメージにないかもしれません.while やfor 文でループするということは,ループの最後まで来たらループの先頭にジャンプしています.if やswitch 文は条件に一致したところに文字通りジャンプします.
 ジャンプについての最適化で一番分かりやすいのは,ループ展開です.
要はジャンプしなければ良いので,ループ回数分内容を展開します.10 回ループするのであれば,内容を10 個分記述すれば良いわけです.プログラムサイズは増えますが,パフォーマンスは向上します.

というところで,e2studio の最適化のコンパイラオプションを見ると,1つ分かる項目が増えます.
3.の項目である『ループ展開』です.
『外部変数へのアクセスを優先』は1,2.の項目と似たようなものですが,厳密には異なるようです.
E2studio_

2014年4月29日 (火)

デバイステスト

とりあえず、FRAM にデータ読み書きができるようになったので、ロボトレ設計時に搭載予定だったディスプレイのテストを始めました。

ディスプレイは4D Systemsの『uOLED-96-G1』。2年くらい前に購入して、手を付けていないものでした。
このディスプレイはシリアル通信でデータを送るので、RX210 からシリアルポートを一本引き出しておきました。

ついでなので、以前購入したBluetooth モジュールもテストしてみました。
Bluetooth モジュールは『JY-MCU BT board V1.05』というやつです。
ペアリング時のピンコード『1234』にしばらくハマりましたが、なんとか動作確認。

やはり、無線でデータ送れると便利ですね。

まだ、ボーレート設定が出来ていませんが、このシリアルポートはuOLED 専用にする予定なので、本格的に使う時にテストします。

2014年4月 1日 (火)

RX210 外部メモリ使用メモ1

自分用のメモとして妄想をアウトプットしておきます。

ロボトレコース情報の保存とデバッグログ用の拡張メモリとして外部メモリを使用します。
外部メモリとして使用するのはCypress社のFM25W256 を2 個。容量は256kb(32kB)x2 です。
インターフェースはSPI で最大周波数は20MHz。セット、ホールド時間は5ns。立ち上がり、立ち下がり時間は50ns。
バーストリード、バーストライトが可能。
アドレスは0000h〜7FFFh。

一方、RX210 はSPI ペリフェラル(RSPI)の最大周波数8MHz。
クロックと分周器の都合で6MHz。
送信バッファレジスタが空の状態でデータレジスタへの書き込みで送信開始。
DMA と組み合わせて、ソフトウェアDMA をトリガにしてデータレジスタに転送する。
バースト転送はできるが、バースト受信はできないみたい。
RSPI は32bit 転送ができるようなので、8bit ずつに分解する手間はなさそう。
6MHz として単純に32bit 転送するには、オペコード8bit とアドレス16bit を含めて56bit あるので、9.3us。

FRAM に保存したデータをRX210 の内部RAM に展開しては意味がないので、毎回ないしは少しまとまった単位でFRAM からデータを取ってくる仕組みが必要。

的外れではないはずだが、こんな感じで上手くいくのかは不明ですね。

2014年3月30日 (日)

ソースコードのバージョン管理

皆様、お久しぶりです。
昨年末ぶりの更新になります。

モチベーションがZero% になっていたり、プライベートで書き物をしていたり、本業で溶けていたりといろいろありました。

やっと書き物も私の手を離れ、先日ロボグラを見に行き、やる気も出てきたのでぼちぼち手を動かそうと思います。

さて本題ですが、皆さんはソースコード管理をどうしているでしょうか。
私は入社するまでプロジェクトのフォルダごとをコピーしていました。入社してからソースコード管理ソフトがあることを知り、昨年から使い始めました。
私はsubversion を使っていますが、git や他のツールを使っている方も多いと思います。
subversion 導入についてはこちらで紹介されてますので参照ください。

私の場合、TortoiseSVN とdropbox を併用しています。
通常、データの保存先は専用のサーバーがあり、多人数で開発するものと思います。
マウスやロボトレなどは個人開発ですし、サーバーを立てるのは大変です。また、データの自動バックアップと他人のPC でソースを見ることを考慮したいと思いました。
そこでweb ストレージサービスの併用です。dropbox はローカルに自動同期され、explorer で操作できるのでサーバーのような使い方ができます。


1.上記で導入したsubversion のリポジトリをローカルのdropbox フォルダに作成します。

Repository_r

ローカルのdropbox フォルダに作成したリポジトリ。

2.ソースコードを管理する任意階層のフォルダにチェックアウトします。

Verdirt04_repository_r

チェックアウト時に指定するリポジトリをローカルのdropbox フォルダにすればOK。

2012年12月15日 (土)

アセンブラの続き

本業でやっているアセンブラに限界が見えてきました.

自分が思っていたよりもずっと限界値が低くて『こんなもんか』という感じです.

いや,もっとお利口な頭脳があれば限界突破出来るのかもしれませんが,製品を作るためのマスト条件ではないので打ち止めです.

それでもC で書くより3倍以上速くなりましたよ!


追記:
全く別のアプローチで最適化したところ,約7 %程速くなりましたcatcat

2012年12月12日 (水)

アセンブラは慣れないです

最近本業でアセンブラを触っているのですが,今まで意識せずに使っていた部分に踏み込んでいるため難しいです.
CPUにくっついている汎用レジスタを意識してプログラムする日が来ようとは….
ここ数日で分かった事は,関数を呼ぶ時は読んだ先でちゃんとレジスタの中身をスタックに退避させておいてあげようということです.
関数の終わりでは退避させたものを復元するわけですが,退避のことを『プッシュ』,復元のことを『ポップ』と言うみたいです.
アセンブラで書くとC で書くよりも効率化出来ますが,効率化すればするほど訳の分からないコードになってしまうのが痛いところですね.