6

簡単な C++ コードを作成し、C++ でテストした後、同じコードを MATLAB に適合させ、mex file_name.cppC++ と同じコンパイラを使用する MATLAB で同じコードを実行しました。コードは次のとおりです。

int k;
for(int j = 0; j < 100;j++){
    for(int i = 0; i < 10000000; i++){
        k++;
    }
    k/=10000000
}

MATLAB コードは次のとおりです。

double a;int j;int i;
double* k;

for(j = 0; j < 100;j++){
    for(i = 0; i < 10000000; i++){
        a = a+1;
    }
    a = a / 10000000;
}

plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
k = mxGetPr(plhs[0]);
*k = (double)a;

このコードを MATLAB 用に編集しました。つまり、適切な型に変更したり、MEX 関数を追加したりしました。結果は、C++ では 3100 ミリ秒であるのに対し、MATLAB では約 900 ミリ秒です。

私が理解していないのは、両方が同じコードを同じコンパイラで実行していることです (MATLAB ではmex -setup、コマンド ラインで記述し、MEX コンパイラとして Visual Studio コンパイラを選択しました)。ただし、MATLAB は約3.5 倍高速です。

高速化のために MATLAB が行っていることと、C++ が行っていないことは何ですか? なぜそんなに大きな違いがあるのか​​ 誰か説明してもらえますか?他のコードをいくつか試しましたが、MATLAB ではすべて 3 ~ 6 倍高速です。

私の PC は 64 ビット Windows 7、C++ には Visual Studio 2010、MATLAB は R2012b です。

Visual Studio のバージョンが原因である可能性はありますか? VS2012に変更すると、速くなりますか?

mex -vの出力はこちらです。

ありがとう、

4

2 に答える 2

3

パフォーマンスは、プラットフォーム、OS、コンパイラなどに大きく依存します。この場合、Matlab が何をしていても、VS2010 コンパイラがしなかった最適化を見つけることができました。VS2012 にアップグレードしても大きな違いはないと思いますが、間違っている可能性があります。結局のところ、それは別のコンパイラです。

これは少し驚くべきことですが、コンパイル フラグを確認し、さまざまな構成でプロファイルを作成してみてください。Matlab のインストールが 32 ビットの場合、それによっても違いが生じる可能性があります。

コードにもわずかな違いがある可能性があります。コードは、パフォーマンスに大きなばらつきがある可能性のある他のライブラリにリンクしている可能性があります。

ここでの教訓は、あるものが他のものよりも優れている理由を正確に特定するのは非常に難しい場合があるということです.

編集:コードはデバッグ用にコンパイルされていると述べました。デバッグ オプションを有効にすると、他の最適化もオフになる可能性があり、各コンパイラは、どの種類のデバッグ情報が重要であり、コードに貼り付ける価値があるかについて異なる考えを持っているため、これはコンパイラが出力するもののバリエーションをさらに増やすだけです。

より一貫した出力を得るために、すべてのデバッグ オプションをオフにすることをお勧めします。同様のレベルの最適化でコンパイルしていることを確認することもお勧めします。

于 2013-09-03T13:22:09.070 に答える
3

C++ コードint kでは内側のループで使用しますが、MATLAB コードでは使用しますdouble a(奇妙なことに、a++表記法をa=a+1... に変更します)。

両方を初期化せずに残します。なぜそれが悪いのかについては、この質問を参照してください。

MEX ファイルはデフォルトで ANSI C です。コードは実際にそのように見えます。;を再確認してくださいmex -setup。C++ コンパイラを選択していると思って、誤って C コンパイラを選択した可能性があります。

また、両方のコンパイルでまったく同じコンパイラ オプションのセットがあることを確認してください。まったく同じです。

しかし、問題の核心は、C++ バージョンで整数演算を実行し、MATLAB バージョンでdouble演算を実行していることだと思います。これにより、大きな違いが生じる可能性があります。

それと、ここですでに述べたこと以外には、違いはないはずです。実際、基本的な最適化を備えた適切なコンパイラーであれば、このループが些細なものであることを検出して、完全に削除できるはずです。

于 2013-09-03T13:59:36.903 に答える