高速化テクニック | |||||||||||||||||||||||||||||||||||||||
手島 知昭![]() |
|||||||||||||||||||||||||||||||||||||||
このページでは手島がプログラミングをしていて,「こうした方がプログラムが高速に動作する」と気づいたテクニックを紹介します. 想定している環境はWindows XP(SP2) + (VC++ .NET) + OpenCVです. あまり高度なことは書いていなくて,初心者を想定した内容となっています. アルゴリズム的な改善には触れておらず,実装面でのテクニックです. 画像処理以外のプログラミングに応用できるかどうかは未知です. 経験則やコンピュータの原理的に早くなるテクニックを紹介しているだけなので,間違い,記憶違い,昔は正しかったけれど今は嘘な情報など, 指摘があれば ![]() |
|||||||||||||||||||||||||||||||||||||||
目次 | |||||||||||||||||||||||||||||||||||||||
ビルド(B)→構成マネージャ(O)→アクティブソリューション構成(A) をDebug→からReleaseに変更します. もしくはツールバーのソリューション構成をReleaseモードに変更することでも可能です. ![]() デフォルトで起動した場合,VC++では「Debugモード」でコンパイルします. このモードでは内部状態をトレースし易い様に,要らぬ情報や機能が追加された状態でコンパイルされます. つまりお荷物が沢山付いているわけですね. Releaseモードにすることで,余分な機能が排除されます. (Dec. 23. 2008 追記) ぶっちゃけると,このページのこれ以降の話はこのスイッチ1つに集約されていると言っても過言ではありません. 多少がんばったところで,Releaseモードで得られるメリットに比べたら小さいでしょう. 有名な名言を2つ紹介しておきます. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. (Donald E. Knuth) We follow two rules in the matter of optimization: Rule 1. Don't do it. Rule 2 (for experts only). Don't do it yet - that is, not until you have a perfectly clear and unoptimized solution. (M.A. Jackson) (追記ここまで) 良い例: 悪い例: 一方で,悪い例では,ループ内でint型の変数aが宣言されています. このループを出るたびに宣言されるので,aは1万回確保され,解放されます. 同様に,変数jもiのループに入るたびに確保,解放されます. aで1万回,jで100回,確保と解放が行われるので,計20200個の命令語が実行されます. 画像処理では,ピクセルの数だけループを回すことはよくあることです. その場合のループは軽く数万〜数十万回処理されます. 宣言は関数の最初にまとめる癖を付けましょう. 補足 実行環境 実行結果[ms]ループを8億回(xffff × x2fff回)
実行結果[ms]ループを5億回(xffff × x1fff回)
しかも単位がmsだからなぁ.実感することは少ないかも. インライン展開を利用する場合はinline宣言を関数の宣言の前に付けます. 例: 一方で,インライン展開を行うと,関数Power内の処理が,呼び出される場所に全て挿入された状態でコンパイルが行われます. 関数を呼ぶ際のオーバヘッドが防げます. ただしループ内など,何度も関数が呼ばれるような状況でないと高速化は期待できません. また,クラスのメンバ関数をinline宣言する場合はヘッダファイル内で定義しないと,効果が出ません. これはヘッダ→ソースコードの順でコンパイルするC++の仕様で,クラス内でインライン展開する場合はヘッダ内で定義する必要があります. しかし,例えば処理A,B,Cそれぞれに対し画像を入力するとする場合,毎回毎回ハードディスクに読み込んでいると時間がかかります. これがハードディスクでなく,ネットワーク越しのドライブならば尚更です. アクセスに要する時間はネットワークディスク>ハードディスク>>メモリです. 極力ロードする回数を減らし,メモリ空間上でコピーして使いまわすようにしましょう. 1から画像処理の関数群を作る場合や,大きな処理のために細かい数多くの画像処理が必要になる場合,ライブラリを利用するのが圧倒的にエラーも少なく,高速に処理が行えます. ライブラリ依存になってしまうため開発が打ち切られたら終了,バグが内在しても自分で取り除くのが難しい,基本を理解しないままになってしまうなど,問題点が無い訳ではありませんが,利用して損は無いでしょう. 多種類の画像処理技術を利用する場合に特に有効です. 悪い例: 良い例: |
Last Updated 29, Mar, 2011.
Since 11, Mar, 2007.