C/C++は低レベル言語であり、他の高レベル言語と比較すると、比較的最適化されたマシンコードを生成することを認識しています。しかし、それよりもはるかに多くのことがあると思います。これは実践からも明らかです。
Gaussianサンプルコレクションのモンテカルロ平均化などの単純な計算を行うと、C++実装とMATLAB実装の間に大きな違いはないことがわかります。実際には、MATLABのパフォーマンスが少し向上します。
数千行のコードを含む大規模なシミュレーションに進むと、実際の画像が徐々に現れます。 C++シミュレーションは、同等のMATLAB実装よりも時間の複雑さで100倍優れた優れたパフォーマンスを示します。
ほとんどの場合、C++のコードはほとんどシリアルであり、明示的にhi-fi最適化は行われません。一方、私の認識では、MATLABは本質的に多くの最適化を行います。これは、たとえば、ランダムサンプルの巨大なチャンクを生成しようとすると表示されます。IT++/GSL/Boostのようなライブラリを使用するC++の同等の実行は比較的低速です(使用されるアルゴリズムはmt19937と同じです)。
私の質問は、パフォーマンスの点でMATLAB/C++の単純なトレードオフがあるかどうかを知ることです。「できる限りC/C++の方が良い」(頻繁に経験する)と言われているようなものですか?別の観点では、「MATLABは快適さ以外に何に適していますか?
ちなみに、ここではコーディング効率のパラメーターは重要ではなく、両方のケースで同じプログラマーを考えています。また、python、Rのような他の選択肢はここでは関係ないと思います。しかし、使用する特定のライブラリへの依存は興味深いはずです。
[私は、通信システムのコーディング理論の博士課程の学生です。私は常にmatlab/C++を使用してシミュレーションを行い、両方のケースで数10Kの行をコーディングする合理的な経験があります]
MatlabとC++を約10年間使用しています。私の研究のために実装されたすべての数値アルゴリズムについて、私は常にMatlabでのプロトタイピングから始め、プロジェクトをC++に変換して10倍から100倍(冗談ではありません)のパフォーマンス改善を得ました。もちろん、最適化されたC++コードを完全にベクトル化されたMatlabコードと比較しています。平均して、改善は約50倍です。
2つのプログラミング言語の両方の背後には多くの微妙な点がありますが、以下は誤解です。
Matlabはスクリプト言語ですが、C++はコンパイルされます
MatlabはJITコンパイラを使用してスクリプトをマシンコードに変換します。Matlabが提供するコンパイラを使用することで、最大1.5倍の速度で速度を向上させることができます。
Matlabコードは完全にベクトル化できるかもしれませんが、C++で手作業でコードを最適化する必要があります
完全にベクトル化されたMatlabコードは、C++/C/Assembly(Intel MKLなど)で記述されたライブラリを呼び出すことができます。しかし、プレーンなC++コードは、最新のコンパイラーによって合理的にベクトル化できます。
Matlabが提供するツールボックスとルーチンは、非常によく調整され、適切なパフォーマンスを備えている必要があります
いいえ。線形代数ルーチン以外のパフォーマンスは一般に悪いです。
ベクトル化されたMatlabコードと比較して、C++で10倍から100倍のパフォーマンスを得ることができる理由:
Matlabで外部ライブラリ(MKL)を呼び出すには時間がかかります。
Matlabのメモリは動的に割り当てられ、解放されます。たとえば、小さな行列の乗算:A = B*C + D*E + F*G
Matlabで2つの一時行列を作成する必要があります。 C++では、事前にメモリを割り当てると、NONEが作成されます。そして、そのステートメントを1000回ループすると想像してください。 C++の別のソリューションは、C++ 11 Rvalueリファレンスによって提供されます。これはC++の最大の改善点の1つであり、C++コードはプレーンなCコードと同じくらい高速になりました。
並列処理を行う場合、Matlabモデルはマルチプロセスであり、C++の方法はマルチスレッドです。並列化が必要な小さなタスクが多数ある場合、C++は最大で多数のスレッドまで線形ゲインを提供しますが、Matlabでパフォーマンスが低下する可能性があります。
C++でのベクトル化には組み込み関数/アセンブリの使用が含まれ、SIMDベクトル化はC++でのみ可能な場合があります。
C++では、経験豊富なプログラマーがL2キャッシュミス、さらにはL1キャッシュミスを完全に回避できるため、CPUを理論上のスループット制限に押し上げることができます。この理由だけでも、MatlabのパフォーマンスはC++に10倍遅れる可能性があります。
C++では、理論的にはIPC =(クロックサイクルごとの命令)に達し、CPUパイプラインがいっぱいになります。
ただし、C++での開発時間もMatlabに比べて10倍です!
C++の代わりにMatlabを使用する必要がある理由:
データの視覚化。私のキャリアはC++なしでも継続できると思いますが、Matlabなしでは美しいプロットを生成できるからといって、Matlabなしでは生き残れません!
低効率ですが、数学的に堅牢な組み込みルーチンとツールボックス。最初に正しい答えを取得してから、効率について話します。 C++で微妙な間違いを犯す可能性があります(たとえば、暗黙的にdoubleをintに変換します)正しい結果を得ることができます。
アイデアを表現し、同僚にコードを提示します。 MatlabコードはC++よりも読みやすく、はるかに短く、Matlabコードはコンパイラなしで正しく実行できます。私は他の人のC++コードを読むことをただ拒否します。コードの品質が保証されていないため、C++ GNU科学ライブラリも使用していません。研究者/エンジニアがC++ライブラリをブラックボックスとして使用し、許可された精度を取るのは危険です。 。商用C/C++ライブラリの場合でも、インテルコンパイラは昨年sin()関数にsignエラーがあり、MKLでも数値精度の問題が発生したことを覚えています。
最後の、しかし少なくともではない:
Matlabコードがベクトル化されると、プログラマーが最適化する余地はほとんどないため、Matlabコードのパフォーマンスは、C++コードと比較してコードの品質にそれほど影響を受けません。そのため、Matlabで計算アルゴリズムを最適化することが最善であり、通常、Matlabでわずかに優れたアルゴリズムはわずかに優れたパフォーマンスを発揮します。一方、C++のアルゴリズムテストでは、まともなプログラマーがほぼ同じ方法で最適化されたアルゴリズムを記述し、コンパイラーがアルゴリズムを異なる方法で最適化しないことを確認する必要があります。
C++とMatlabでの最近の経験:
過去1年間にいくつかの大規模なMatlabデータ分析ツールを作成しましたが、Matlabの速度が遅いことに苦しみました。しかし、次の手法によりMatlabプログラムの速度を10倍向上させることができました。
Matlabスクリプトを実行/プロファイルし、C/C++で重要なルーチンを再実装し、MEXでコンパイルします。重要なルーチンは、ほとんど論理的に単純ですが、数値的には重いです。これにより、速度が5倍向上します。
Matlabツールボックスに同梱されている「.m」ファイルを、すべての不要な安全性チェックと出力パラメーターの計算にコメントすることで簡素化します。変更されたコードは、残りのユーザースクリプトと共に配布できないことに注意してください。これにより、速度がさらに2倍向上します(C/C++およびMEXの後)。
改善されたコードは、Matlabで〜98%、C++で〜2%です。
ツール全体をC++でコーディングすると、さらに2倍(合計20倍)速度を改善できると考えています。これは、計算ルーチンの〜100倍の速度改善です。その後、ハードドライブのI/Oがプログラムの実行時間を支配します。
Mathworksエンジニアへの質問:
Matlabコードが完全にベクトル化されている場合、パフォーマンスを制限する要因の1つは行列のインデックス付け操作です。たとえば、5000x5000の次元を持つマトリックスAで差分演算を実行する必要があります。
B = A(:,2:end)-A(:,1:end-1)
行列のインデックス操作により、MatlabコードはC++コードよりも数倍遅くなります。マトリックスのインデックス作成のパフォーマンスを改善できますか?
Matlabのパフォーマンスはコーディングスタイルに強く依存している(C++のパフォーマンスよりもはるかに大きい)ため、私の経験(両言語でのコンピュータービジョンと画像処理の数年)では、この質問に対する簡単な答えはありません。
一般的に、Matlabは古典的なC++/Fortranベースの線形代数ライブラリをラップします。したがって、x = A\b
のようなものは非常に高速になります。また、Matlabはこれらのタイプの問題に対して最も効率的なソルバーを選択するのに適しています。そのため、x = A\b
については、Matlabはマトリックスのサイズを調べ、適切な低レベルルーチンを選択します。
また、コードを「ベクトル化」する場合、つまりfor
ループを避け、データにアクセスするためにインデックス配列またはブール配列を使用する場合、Matlabは大きな行列のデータ操作にも威力を発揮します。このようなものは非常に最適化されています。
他のルーチンの場合、Matlabコードで記述されているものもあれば、C/C++実装(Delaunayなど)を指しているものもあります。 edit some_routine.m
と入力して、これを自分で確認できます。これによりコードが開き、それがすべてMatlabであるか、コンパイルされたものの単なるラッパーであるかがわかります。
Matlabは、主に快適さのためだと思いますが、快適さはコーディング時間と最終的にはお金につながるため、Matlabは業界で使用されています。また、プログラミングのトレーニングはほとんどなく、コンピューターサイエンス以外の分野のエンジニアも簡単に学ぶことができます。
博士課程の学生として、また10年の長さのMatlabユーザーとして、私はPOVを共有できてうれしいです:
Matlabは、特にGUI、高レベル分析(周波数ドメイン、LS最適化など)を扱う場合、アルゴリズムの開発とプロトタイピングに最適なツールです。高速コーディング、強力な構文([]、{}などについて考えてください)。
処理チェーンがより安定して定義され、データのサイズが大きくなると、C/C++に移行します。
その言語がスクリプトのようなものであると考えると、Matlabの主な制限が上がります:呼び出されたサブルーチンが再びC/C++にあるため、cicle(arrayfun、cellfunまたは他のマトリックスプロシージャを使用)を避ける限り、パフォーマンスは高くなります。
あなたの質問に答えるのは難しいです。一般に、C++は高速ですが、Matlabの適切に記述されたアルゴリズムを使用すると、C++を上回ることができます。場合によっては、Matlabはコードを並列化できます。これは、多くの場合C++で手動で実行する必要があります。 MathlabはC++コードをエクスポートできます。
私の結論は、答えを得るには両方のプログラムのパフォーマンスを測定する必要があるということです。ただし、MatlabとC++全体ではなく、2つの実装を比較します。
Matlabは、線形代数と配列/行列演算で非常にうまく機能します。これらは、基礎となる演算でいくつかの追加の最適化を行っているように見えるためです。
インタープリタ型言語として、Matlabは、Matlabループが遅いことを伝統的に意味していた内部オーバーヘッドのために、Matlab関数が呼び出されるたびに時間を失います。これは近年、JITコンパイラーの大幅な改善のおかげで多少軽減されました(SOでMatlabの「パフォーマンス」の質問を検索してください)。関数呼び出しのオーバーヘッドの結果として、裏でC/C++に実装されていないMatlab関数(edit functionName
を呼び出して、Matlabで記述されているかどうかを確認)は、C/C++の関数よりも遅くなります。
最後に、Matlabはユーザーフレンドリーであることを試み、(関数呼び出しのオーバーヘッドにより)時間を要する「不要な」入力チェックを行う場合があります。たとえば、ismember
がソートされた入力を取得することがわかっている場合、ismembc
を直接呼び出すことができ(舞台裏のコンパイル済み関数)、かなりの時間を節約できます。
少なくとも4つのフォールドの違いを考慮できると思います。
1〜3は、プログラミング言語の2つのファミリ間の比較に簡単に一般化できます。
4の場合、MATLAB
は行列演算用に最適化されます。したがって、MATLAB
でさらに多くのコードをベクトル化できれば、パフォーマンスを大幅に向上させることができます。逆に、多くのloops
が必要な場合は、C++
を使用するか、mex
ファイルを作成することをためらわないでください。
やはり難しい質問です。
MATLABからC++に切り替えると、速度が5.5倍向上しました。これは、ロボットコントローラーのループとodeの解決のためのものでした。 MATLABコードの最適化に何時間も費やしましたが、C++を最適化することはほとんどありませんでした(もう少し努力すれば10倍高速になったはずです)。
ただし、MATLABコードにGUIを追加するのは簡単だったので、今でも頻繁に使用しています。他の人が言ったように、最初にMATLABでプロトタイプを作成するのは素晴らしいことでした。これにより、C++での実装がはるかに簡単になりました。
最終的なプログラムの速度に加えて、コードの総開発時間、つまり書く時間だけでなく、デバッグする時間なども考慮する必要があります。Matlab(およびそのオープンソースの対応物、- Octave )は、視覚化機能により、迅速なプロトタイピングに適しています。
ストレートC++を使用している場合(つまり、マトリックスライブラリがない場合)、Matlabコードと同等のC++コードを記述するのに時間がかかる場合があります(たとえば、10秒しか実行しないC++コードを10時間費やしても意味がない場合があります)書き込みに5分かかったMatlabプログラムと比較して、高速です)。
ただし、MatlabのようなAPIを提供する Armadillo などの専用C++マトリックスライブラリがあります。これは、Matlabから呼び出すことができるパフォーマンスクリティカルなコードを記述したり、Matlabコードを「実際の」プログラムに変換するのに役立ちます。
一部のMatlabコードは、マルチスレッドを組み込んだ標準の線形代数フィクションを使用します。したがって、シーケンシャルCコードよりも高速であるように見えます。