More Related Content
Similar to プログラムの高速化 (20)
More from 東海北陸ロボコン 交流会 (8)
プログラムの高速化
- 5. 手法①
• 繰り返しはカウントダウンで
例 int i;
for(i = 0; i < HOGE; i++)
↓
for(i = HOGE; i > 0; i--)
終了条件の判定はZフラグを見ており、条件を0にしてやれば条件比
較をしなくてもZフラグが立つためアセンブラレベルでは命令数が減る
ため(環境による)
(速度は体感できるレベルではないが使用メモリは削減できる)
- 7. 手法③
• 関数を「static inline」修飾する
例 uint16_t GetBatteryVoltage(void){
return HOGE;
}
↓
static inline uint16_t GetBatteryVolutage(void){
return HOGE;
}
関数は呼び出される際に少なからずオーバーヘッドが発生する。
インライン展開を行うことで関数を呼び出すのではなくその位置に埋め込まれる。
(関数内の処理によっては展開されないこともある。また、static修飾をしていない
場合も展開されないことがある)
- 8. 手法④
• 値渡しではなくポインタ渡しをする
例 void Func1(struct Data_t dat){
hoge;
}
↓
void Func1(struct Data_t* dat){
hoge;
}
値渡しでは、引数とした変数がメモリ空間の別の場所にコピーされるので特にサ
イズの大きな構造体やインスタンスでは時間がかかる(体感ではゼロ時間)。これ
を参照渡しにすることでコピーは発生せず時間が短縮できる。
ただし、参照したからといって関数内で実体をコピーしていたらこれをするメリット
はない(と思う)
- 10. 手法⑥
• 「register」修飾(アーキテクチャ的な話になります)
例 int i;
for(i = 0;i < 1000000; i++)
hoge;
↓
register int i;
for(i= 0; i < 1000000; i++)
hoge;
CPUにとってメモリアクセスはものすごく(?)遅い
高速化するためにCPUにはキャッシュメモリが設けられているが、実際の計算時
にはレジスタに格納する必要がありそのためのアクセスに時間を要する。そこで
最初からこのレジスタに変数を確保するのがこのキーワードである。register修飾
された変数はアドレス参照することはできない。
- 11. 手法⑦
• 変数の「static」修飾(何回も呼び出される関数を想定してください)
例 void Func1(){
int hoge;
hoga;
}
↓
void Func1(){
static int hoge;
hoge++;
hoga;
}
一つ目のFunc1では関数が呼び出されるたびにhogeが確保され関数終了時には破棄されてしまう。つまり、呼び出すたびに再確保
という無駄時間が存在する。対して、下の関数ではstatic宣言をしているため破棄されずに常に残っているため無駄時間が発生し
ない。
もっというと、static変数は.bssセクションに確保されるため必ずゼロで初期化されています。(C言語の規則です。)セクションはコンパ
イル時の配置に関する部分(のはず)なので説明は省きますが、気になったらググるなりどうぞ。リンカスクリプトを読んでもいいかも