2011-02-06 21 views
2

は、私は、次の2つのオプションを試し両方でres。そして驚くべきことに、私はオプション2がより速いことを発見しました。MATLAB行列乗算は

これはどのように説明できますか?

編集: 私はそれはあなたが適切に行列を乗算していないように私には見えます

K=10000; 
clear t1 t2 
t1=zeros(K,1); 
t2=zeros(K,1); 

for k=1:K 
    clear res 
    x = rand(100,100); 
    a = rand(100,100); 
    tic 
    res = x*a; 
    t1(k) = toc; 
end 

for k=1:K 
    clear res2 
    res2 = zeros(100,100); 
    x = rand(100,100); 
    a = rand(100,100); 
    tic 
    for i = 1:100 
     res2(:,i) = x*a(:,i); 
    end 
    t2(k) = toc; 
end 
+0

OSX、2010bでは、バージョン1の中央値は0.0001、バージョン2の中央値は0.0008です。言い換えれば、ベクトル化されたバージョンは約7倍高速です。 – Jonas

+0

いくつかのバラツキを解消するには、2回目の実行を開始する前にランダムジェネレータをリセットするとよいでしょう。いずれにしても、私は最初の選択肢が数倍速いことも発見します。 –

答えて

2

私は、2つの方法のタイミングのばらつきと、なぜ人々が異なる相対的なスピードを取っているのかを確認できます。

Matlabバージョン2008a(またはそのリリースに近いバージョン)より前のバージョンでは、インタープリタ(非常に読みやすいスクリプトとコードの下位レベルの実装の間のレイヤー)は、Matlabコードで大きな打撃を受けました毎回forループを通してコードを再解釈します。

インタプリタは現代版のMatlabを実行しているときに徐々に良くなっているので、通訳者はあなたのコードを見て、「ああ、彼が何をしているか知っています。ビットを "し、コードを再解釈することによって他の場合にかかるヒットを回避します。

私は単なる死人が知りたくないというインタプリタの最適化の細部のために、同じ時間内に行列の乗算を実行する2つの方法。

私たちはこれから取るべき広範な教訓は、すべてのバージョンが等しいとは限りません。私はSimBiologyとParallel Computing Toolboxの2つのMatlabアドオンを使用して、いくつかの最先端のケースに取り組んでいます(SimBiologyとParallel Computing Toolboxはどちらも(特にあなたが一緒に働かせたい場合)バージョンは実行速度に左右されます。その他の安定性の問題。 Matlabの最新の3つのリリースを維持し、それぞれのバージョンから同じ回答が得られることをテストし、いくつかの機能で問題が見つかった場合は、以前のバージョンにロールバックすることがあります。これは大部分の人にとってはおそらく過剰ですが、バージョンの違いを知ることができます。

これが役に立ちます。

編集:

明確にするために、コードベクトル化は依然として重要です。しかし、のような特定のスクリプト:

x_slow = zeros(1,1e5); 
x_fast = zeros(1,1e5); 


tic; 
for i=1:1e5 
    x_slow(i) = log(i); 
end 
time_slow = toc; % evaluates for me in .0132 seconds 

tic; 
x_fast = log(1:1e5); 
time_fast = toc; % evaluates for me in .0055 seconds 

time_slowとtime_fast間の格差は、通訳の改善に基づいて、過去いくつかのバージョンでは減少しています。私が信じていた例は、2000年対2008年のものでしたが、それは私の思い出しの対象です。

OliとYukによって対処されたことが起こっている可能性があります。中TIME_1とtime_2の違いがあることが多い。

tic; x = log(1:1e5); time_1 = toc 
tic; x = log(1:1e5); time_2 = toc 

だから、1件の評価対百万評価のテストは、メモリxに(キャッシュまたはなしで)ある場所に応じて、貴重なものです。

これは再び役立ちます。

+0

本当ですか?ソースコードはすべての反復で再解析されますか?私はそれが信じがたいことが分かります!あなたはそれのための引用を持っていますか? –

+0

参考、恐れはありません。これは、私が約2年前にHPCの講義から思い出したことでした。私は何を意味するかを明確にするために投稿を編集しました。 – Sevenless

-3

を試してみました、あなたは行列のX行列とj番目の列、そのかもしれないのi番目の行からすべての製品を合計する必要があります理由がある。 hereを参照してください。

+2

これは適切な行列乗算です... –

2

これは、キャッシングの効果である可能性があります。 aは、2番目のバージョンを実行する頃に既にキャッシュに入っているので、利点があります。それを公正にするために、独立した入力を作成してみてください。また、おそらく時間を測定する方が良いでしょう。外部効果による典型的な変動を排除するために、これを100万回繰り返す。

3

両方のコードをループで1000回実行します。平均して(ただし必ずしもそうではありません)、最初のベクトル化されたコードは3〜4倍高速でした。私は結果変数をクリアし、タイマーを開始する前に事前に割り当てました。

x = rand(100,100); 
a = rand(100,100); 

K=1000; 
clear t1 t2 
t1=zeros(K,1); 
t2=zeros(K,1); 

for k=1:K 
    clear res 
    tic 
    res = x*a; 
    t1(k) = toc; 
end 

for k=1:K 
    clear res2 
    res2 = zeros(100,100); 
    tic 
    for i = 1:100 
     res2(:,i) = x*a(:,i); 
    end 
    t2(k) = toc; 
end 

したがって、1回の実行に基づいて決してタイミングを決めることはできません。

+0

私はあなたのコードを修正し、質問を編集しました。私のマシンで、別のxとaを使用すると、各繰り返しで2番目のバージョンはまだまだ高速です。 – extraeee