2016-05-01 13 views
-1

2つのアルゴリズムAlg_x、Alg_yの実行時間を比較する必要があります。しかしながら、Alg_xは多くの行列乗算を含み、Alg_yは多くの要素単位の演算(例えば、2つの数/ベクトルの総和および累積)を含む。理論的には、Alg_xとAlg_yの実行時間は同じです。しかし、Matlabでは行列乗算が特別に設計され、最適化されているため、Alg_xはAlg_yよりもはるかに高速に実行できます。行列の乗算のような演算で 'コードの最適化'を避けるには?

次に、私の問題は、実行時間を公正に比較し、理論上の時間の複雑さを反映するために、どのように「コード最適化」を終了するかです。

%%%%% X = randn(1000,2000); 

Alg_x

tic; 
temp = X*X'; 
toc 

Alg_y

[d,n] = size(X); 
temp = zeros(d,d); 
tic; 
for i =1:n 
    x = X(:,i); 
    temp = temp+x*x'; 
end 
toc 

Alg_xがはるかに速く実行中に上記2つの符号は、同一の出力を有します。さらに、Alg_yは、削除した後もずっと速く実行されます。x = X(:、i); temp = temp + x * x ';だから、Alg_yの実行速度を遅くするのはという繰り返しの場合はだと思います。

私はこのような誤植を閉じて避けたいと思っています。以下は、は私がCUDA、C++、C#、およびJavaでいくつかのベンチマークを作り、検証およびマトリックス生成のためのMATLABを使用していますWhy is MATLAB so fast in matrix multiplication?

から抽出されたものです。しかし、私がMATLABを掛け合わせると、2048x2048とさらに大きな行列さえもほぼ即座に乗算されます。

   1024x1024 2048x2048 4096x4096 
      --------- --------- --------- 
CUDA C (ms)  43.11  391.05  3407.99 
C++ (ms)  6137.10 64369.29 551390.93 
C# (ms)  10509.00 300684.00 2527250.00 
Java (ms)  9149.90 92562.28 838357.94 
MATLAB (ms)  75.01  423.10  3133.90 

CUDAだけが競争力がありますが、私は少なくともC++はいくらか近くにあり、60倍も遅くないと考えました。

私の質問は - MATLABはどうしていますか?

C++コード:

float temp = 0; 
timer.start(); 
for(int j = 0; j < rozmer; j++) 
{ 
    for (int k = 0; k < rozmer; k++) 
    { 
     temp = 0; 
     for (int m = 0; m < rozmer; m++) 
     { 
      temp = temp + matice1[j][m] * matice2[m][k]; 
     } 
     matice3[j][k] = temp; 
    } 
} 
timer.stop(); 

編集: また、私はC#の結果について考えて何を知りません。アルゴリズムはC++やJavaとまったく同じですが、1024から巨大なジャンプ2048がありますか?

EDIT2: 更新MATLABおよび4096×4096の結果

+1

行列の乗算は高速に**設計されています**。これは内部的にSuiteSparseを使用して高速な計算時間を実現します。行列の乗算がMATLABで提供する高速アルゴリズムを使用する以外に選択肢はありません(どうしてあなたはやりたくないのですか?)。なぜこの努力をしていますか?私が提案をすることができれば、あなたはJITをオフにした方がより理論的な観点から見ることができます。 JITはあなたの "理論的"時間測定を混乱させるかもしれない 'for 'ループの実行を加速します。コマンドプロンプトで 'feature accel off;'と入力して、ループコードをもう一度試してください。 – rayryeng

+0

メモリ上のこの記事(https://people.freebsd.org/~lstewart/articles/cpumemory.pdf)では、なぜマトリックス行列乗算をその行列ベクトル乗算のリストよりもはるかに速く実行するように記述することができるのかを詳しく説明しています。主な理由は、キャッシュの処理方法です。 FLOPSはコンピューティングの唯一のパフォーマンス指標ではなく、アルゴリズムの複雑さです(log(n)は一定であるかもしれません)。 *理論的な時間複雑度*メトリックはどのように説明しますか? –

+0

こんにちは、お世話になりました。 @FlorentDUGUET私の時間複雑さ測定基準はちょうどフロップであり、複雑さはキャッシュがどのように働くか無視します。 – olivia

答えて

1

私は、「どのようにMATLABが速いということをしているのですか?」あなたの質問に答えています。

MATLABは、行列乗算にIntel MKLを使用します。
これは、すべてのコアとそのベクトル処理ユニット(SSE/AVX)を活用して高度に最適化されたコードです。
さらにCPUのキャッシュレイアウトに合わせて最適化されています。

あなたのコードはそうしないので、テーブルに多くの利益をもたらします。

MATLABでMKLを無効にする方法があるかもしれません。
これまでのところ、私はそれを置き換える方法しか見ていませんでした。

+0

こんにちは、あなたの答えに感謝します。あなたの答えをサポートするためにMathWorksから公式な文書がいくつかありますか?事前に多くの感謝。 – olivia

+0

MATLABで 'version -blas'を使用し、そのBLASエンジンを見ることができます(これはインテルMKLと書いてあります)。 – Royi

+0

多くのおかげです。ところで、私はどの論理的な文書から「CPUのキャッシュレイアウトに合わせて最適化されているか」ということを知ることができます。私は、あなたが話していることが正しいことを知っていますが、私は公式文書によって他の人たちに説得しなければなりません。 – olivia