2009-08-04 25 views
8

私はMatlabの画像処理コードがかなり遅く、C/C++に変換する準備ができています。私は実際にどのようにmatlabが動作し、どのようにコードが実行されるかについてはあまり知らないですが、私は期待していたスピードアップの種類を聞くことに興味があります。明らかにこれに影響する多くの変数がありますが、私はあなた自身の経験からおそらくガイドを探しています。MatlabからC++への変換のスピードアップ

おかげ

Zenna

+8

ええと...いくつかのコード例は素晴らしいでしょう。あなたはMatlabでゆっくりとしたアルゴリズムをとることはできませんし、高速化するための変換が必要です。あなたはインタプリタと戦っていないかもしれません。アルゴリズムは –

答えて

8

ほとんどの場合、Matlabのループの緊張度によって異なります。組み込みのMatlab画像処理関数を呼び出すだけでは、パフォーマンスを向上させることができない可能性があります(おそらくそれを傷つける可能性があります)。イメージピクセルをループしたり、何らかのブロック処理を行っている場合、大きな改善が見られるかもしれません。いくつかのループを実行しているが、各反復内の処理量が大きい場合は、改善がほとんどまたは全く見られない場合があります。

私がMatlabを見ているところは、実行されるすべての行にある程度のオーバーヘッドがあることです。解を行列の乗算やその他のベクトル/行列演算の形にすることができれば、そのオーバーヘッドに一度しか苦しんではいけません。ただし、ループでは、ループが繰り返されるたびにオーバーヘッドが発生します。また、Matlabの画像処理関数のほとんどは、最適化されたライブラリに呼び出すだけなので、どこで改善できるか分からない限り、再作成しないでください。

私は、CとMatlabの組み合わせを使用するのが最善の方法だと分かりました。操作が容易にベクトル化できるとき(ベクトル/行列演算の観点から)、Matlabを使用します。これは、最も直感的であると思われる角度とは異なる角度から解決策に来ることを意味する可能性があります。また、Matlabのプロットやビジュアライゼーションに打撃を与えるのは難しいので、C/C++で表示する方法がプロジェクトの一部である場合を除いて、すべてのC/C++ソリューションに移行することは間違いありません。

ベクトル化するのが比較的簡単な方法を考え出すことができない場合は、Matlabから呼び出せるC mex関数でタイトなループを必要とする処理の部分を実装するだけです。この場合、C++の代わりにCを使用する傾向があります。プロセスは比較的小さく、複雑なデータ抽象化を必要としないはずですが、C++もうまく機能します。 Matlabがその行列を構成する方法であるため、キャッシュヒットを最大にするために、列の主な順序で画像データにアクセスするようにしてください。

+2

JITアクセラレータの導入により、過去のような "for loop penalty"は本当に懸念されていません。実際のボトルネックを見つけるにはプロファイラを使用してください。 – MatlabDoug

+1

ええ、私は確かにそのルートを最初に行くだろうが、私はまだ最適化を伴うCが良いかもしれない状況を発見した。それはちょうどJITコンパイラを利用する上で私の限られた知識かもしれない。 –

+0

@MatlabDoug:JITアクセラレータとプロファイラを拡張することはできますか?私は多くのMATLABプログラミングをしていますが、これまで聞いたことはありませんが、面白いと思うかもしれません。多分、Matlabは良いやり方です。あなたはいくつかのリンクを提供することができますか?ありがとう。 – SSilk

4

それは本当にあなたのMATLABコードの品質と何それはあなたがやっているであるに依存します。 Matlabのエキスパートが作成した慣習的なMatlabコードは、特に最適化の専門家でなく、言語の切り替えによるスピードアップを期待している場合には、勝てないでしょう。たとえば、CベースのFFTライブラリのほうがMatlabのFFTと一致していないものもあります。

しかし、あまり書かれていないMatlabプログラムと平均的に書かれたC++のプログラムを比較すると、私の経験上、あなたは一桁の大きさを見ていると言えます。

+3

かもしれません.FFTの場合、MatlabはC言語で実装されているFFTW(「西洋で最も高速なフーリエ変換」http://www.fftw.orgを参照)を使用します、Objective Camlによって生成されたCコード、http://www.fftw.org/pldi99.pdfを参照)。 – las3rjock

3

どのようなスピードアップが得られるかもしれないのかという質問に対する短い答えは、「それは依存しています」です。

Matlabはインタプリタなので、全体的にネイティブのC++コードよりもはるかに遅いです。しかし、多くのMATLAB関数は最適化されており、最近のバージョンにはJITが含まれています。だからあなたは、CですべてのMATLABコードを書き換えるか、重要な部分だけを書き直すか、より高速に動作するようにMATLABコードを最適化するかどうかを決める必要があります。

まず、Matlabの組み込みプロファイリングツールを使用して、アプリケーションのパフォーマンスボトルネックを見つけることをお勧めします。より良いパフォーマンスを得るために、MATLABコードを微調整することができます。経験則は、一度に1つの要素を反復するのではなく、ベクトル化された配列操作を使用してループを回避することです。

+0

JITアクセラレータの導入により、 "for loop penalty"はこれまでのように心配するものではありません。真のボトルネックを見つけるには、プロファイラを使用します。 – MatlabDoug

1

たとえば、matlabはFFTアルゴリズムを実装するためにFFTWライブラリを使用します。そのライブラリのパフォーマンスは、ほとんど克服することが不可能です。私が知っている唯一のものは、Intel Math Kernel Library(MKL)ですが、商用です。だからまず第一に、私が見つけることができる数学的なライブラリのすべてを使用することをお勧めします。 Matlabはその背後でそれをやっています。

これは時々matlabを打つことは困難であることは事実です。しかし、問題は、matlabのプロファイラがコードを改善する方法についての十分な情報を提供するとは限りませんということです。あなたはいくつかのmatlabのメソッドがほとんどの時間を取っていることを知っていますが、そのメソッドがブラックボックスなので、別の方法でそれらを呼び出すパフォーマンスを向上させる方法であるかどうかを常に知っているわけではありません。

C/C++には、valgirndのようなツールがあります。このツールを使用すると、コンパイラが生成しているアセンブラであっても、コンパイラがメソッドをインライン化するコードを改善できるようになります。しかし、やはりmatlabは舞台裏でプロの数学ライブラリを使用しています。あなたがあなたのMATLABコードを実行するときに、ほとんどの時間がそれらのライブラリに費やされていれば、パフォーマンスを改善することは困難です。

私は別のアプローチを試すことができますか?あなたは、そのコードをネイティブコードに移動する価値があるかどうかを確認するために、matlabプロファイラを使用してボトルネックを分析することができます。 Matlabはそれを可能にします。あなたはまた、他の方法でそれを行うことができます。あなたはC/C++でいくつかの接着剤を実装することができますし、あなたのネイティブコードがmatlabの速度が遅いことを経験したいくつかの操作のためにmatlabを呼び出します。

1

イメージ処理の場合、目覚ましいスピードアップを得ることができます。しかし、これは本当にあなたがMATLABコードを書く上でどれほど優れているかにかかっています。多くのことをベクトル化したり、組み込み関数で処理することができます。その種のコードは急速に爆発的です。

しかし、多くのループ(画像のすべてのピクセルをループする)のようにコードを見つけると、非常に遅くなり、ベクトル化によって100倍以上のスピードアップが得られます。

MATLABでコードを "正しく"実行するのが難しい場合は、Cに切り替えることは実行可能な選択肢になります。私は学校でコンピュータビジョンプロジェクトを行った(3D点再構成)、これを明確に示した。 C++とOpenCVで実装されたプロジェクトが終了したとき、他のグループプロジェクトの1つはまだ画像をロードしていませんでした。それらはMATLABで書かれています。我々はそれをタイムアウトしたことはありませんが、私のと推測されます。私たちのバージョンは約10倍速く走っています。

しかし、MATLABコードはおそらく最適化されていない可能性があります。だからベンチマークとしてはあまり役に立ちません。

+0

JITアクセラレータが導入されたことで、 "for loop penalty"は過去のように本当に懸念されていません。真のボトルネックを見つけるには、プロファイラを使用します。 – MatlabDoug

+0

はい、聞いたこともあります。残念ながら、最新のMATLABバージョンではまだ作業していませんでした。( –

0

他の人たちと同じように、MATLABプロファイラを使用してボトルネックを確認します。それが行列の数値計算であれば、MATLABを打ち負かすにはかなり高いバーがあります。条件文や関数呼び出しが多い場合は、速度を向上させる可能性が高くなります。

MATLABとC++の間でデータが転送される回数を最小限に抑えてください。大規模なデータアレイを1つの大きな塊に送信する場合は、高速になる可能性があります。さもなければ、あなたがC++プログラムが高速であっても、データ変換の速度上の利点を失うかもしれません。

また、あなたのアルゴリズムを見て、Javaの使用を検討します。 MATLABはすでにJRE上で動作しているので、MATLABからカスタムJavaコードを呼び出すことは非常に便利です。 MATLAB関数とカスタムJavaコードの間で大きなデータ配列を転送する速度に非常に感銘を受けました。私は数年前にMATLABをスピードアップするためにC++(MEXなどを使用)でアルゴリズムを実装することを検討しましたが、すべてのデータ構造を処理するのは悪夢のように見えました。私はWindowsマシン上で実行していたので、COM/ActiveXを代わりに使用してしまいました。そして、インターフェイスはずっと簡単でした。

数値的な問題を解決するために多くの低レベルのプログラミングを行った後、数値精度からプログラミングのメンテナンスに至るまで、何がうまくいかないのかをよく理解しています。 C/C++よりも高いレベルの言語を選択してください。

1

私は、C++でmatlabルーチンをエクスポートして、mexとしてVisual Studio C++でコンパイルしています。スピードアップは10倍でした。もし私がマルチコアを使用するならば、私は適切に3倍のスピードを持ちます。

斜面に斜面があり、行列の単一成分で何かを行うと、y(m、n)= x(m)* a - x(m-1)良いスピードを持っています。

多くのmatlab関数を計算に使用すると、matlab関数自体が多くの演算を行う場合、C++でコードを書き出すのはあまり意味がありません。