新人技術者のためのロジカル・シンキング入門(8) ―― CPUの演算量をひたすら削る

冴木 元

tag: 組み込み

技術解説 2008年10月21日

【3】コンパイル結果の無駄の見抜き方(2/2)

● ループの外に命令を追い出す

 コンパイル結果の無駄を見抜く方法の二つ目は,「ループの中に注目する」ということです(図8).ループの中の処理は,ループの中の演算量にループ回数を掛け算したものが全体の処理量となります.そのため,ループの中の処理は削減効果が高いので,どのようなアーキテクチャのCPUを用いて実装する場合でも,ループの中の処理をいかにして減らすかというのが,最適化に当たっては常にポイントとなります(図9)

zu08_01.gif
図8 ループの中は削減効果が高い
ループ中の演算が20サイクルあったとする.ループ回数が200回なら,その部分の処理量は20×200=4000サイクルとなる.ループ中の処理は削減効果が高いので,最適化する際にはまず,ループの中に注目する.

zu09_01.gif
図9 ループの中に注目
コンパイル結果の無駄を見抜くには,ループ中の無駄な命令をループの外にいかにして追い出すかに注目するとよい.ループの外でも実装できる命令は,なるべく外に追い出すこと.具体例を図10図11に挙げた.

 ループの中の処理を工夫によって減らせるものとしては,例えば,テーブルのアドレス計算などがあります.テーブルのようにデータが隣り合わせになっている場合,データをループの中で次々にLOADする場合は,

  1. 先頭アドレスのLOAD
  2. オフセットの計算
  3. 先頭アドレス+オフセットの加算
  4. (3)で求めたアドレスからレジスタへLOAD

という一連の処理を行うことになります.

 コンパイル結果を眺めたとき,これらがすべてループの中で行われていたとしたら,最適化の余地ありといえます(図10).これを最適化した具体例を図11に示します.LOAD対象のデータが隣り合っている事実に着目することによって,最適化のヒントが得られます.図10の(3)で求める先頭アドレス+オフセットという値は,LOADの度に1ずつ増えていくだけです.それならば,このアドレス値をループの外でレジスタに格納しておいて,ループの中でインクリメントしていけばよい,ということになるでしょう.

zu10_01.gif
図10 最適化前のアドレス計算
テーブルのように隣り合わせのデータをループの中で次々とLOADする場合,①~④の処理を順にこなすことになる.これらがすべてループの中にあったら非効率的である.いかにして最適化するか?

zu11_01.gif
図11 最適化後のアドレス計算
隣り合わせのデータを順にLOADするなら,オフセット値は一つずつインクリメント(増分)すれば求められることになる.ここに注目して,(1)~(2)のように命令を書き換える.図10と比較すると,ループ中の命令は四つから二つに削減される.

 図10図11を見比べてみてください.この工夫で,ループの中の命令が四つから二つに減りました.

組み込みキャッチアップ

お知らせ 一覧を見る

電子書籍の最新刊! FPGAマガジン No.12『ARMコアFPGA×Linux初体験』好評発売中

FPGAマガジン No.11『性能UP! アルゴリズム×手仕上げHDL』好評発売中! PDF版もあります

PICK UP用語

EV(電気自動車)

関連記事

EnOcean

関連記事

Android

関連記事

ニュース 一覧を見る
Tech Villageブログ

渡辺のぼるのロボコン・プロモータ日記

2年ぶりのブログ更新w

2016年10月 9日

Hamana Project

Hamana-8最終打ち上げ報告(その2)

2012年6月26日