2016-09-24 2 views
1

MSVC++でコンパイルすると、バージョン1がバージョン2より速いのはなぜですか?キャッシュフレンドリーなループよりも速く2d-arrayでキャッシュされないループをキャッシュします

バージョン1:

for (int i = 0; i < N; ++i) 
    for (int j = 0; j < N; ++j) 
     for (int k = 0; k < N; ++k) 
      res1[i][j] += mat1[i][k] * mat2[k][j]; 

バージョン2:

​​

(N = 1000; RES1、MAT1、MAT2ダブル[N]である[N]アレイ)

[j] [k]がキャッシュフレンドリである(mat2 [j] [k]をRAMからcacheにロードするときにmat2 [j] [k]にループするため、 +1]、mat2 [j] [k + 2]、...も同じcachline上にあるのでロードされます))?

(「#pragma optimize( ""、off)」を使用してコンパイラの最適化をオフにした場合)、バージョン2はバージョン1より高速ですが、コードはかなり遅く(明らかに)実行されます。

EDIT:

パフォーマンス:(時間WINDOWS.H ==> QueryPerformanceCounterの使用して測定)コンパイラの最適化で

を:バージョン1:〜493ミリ。 Version2:954 ms コンパイラ最適化なし:Version1:〜3868 ms;バージョン2:〜の最適化を使用して2266ミリ秒

+1

有効になっている最適化の実際の数値は何ですか? – 2501

+0

アセンブリを見ましたか? 'res1'、' mat1'、 'mat2'はどのような型ですか? – kfsone

答えて

2

は、最初のバージョンのため、コンパイラは明らかに内側の2つのループを並べ替えることができます。

for (int i = 0; i < N; ++i) 
    for (int k = 0; k < N; ++k) 
     for (int j = 0; j < N; ++j) 
      res1[i][j] += mat1[i][k] * mat2[k][j];  

これは、キャッシュの観点から第二に似た最初のバージョンを作成します意識。

最初のバージョンが2倍速い理由は、上記の最適化を行った後、内側のループで変更されないため、おそらく2番目の語句のキャッシュになります。mat1[i][k]

関連する問題