2017-06-28 3 views
1

2つの行列の内積を計算するためにEigenを使用しました。最初の行列はA =(B C).eval()で、2番目の行列はD =(E F).eval()です。ここでB、C、E、Fは同じサイズ(1500 * 1500)ですが、値は異なります。私は最初の1つのコストが約200ミリ秒であるのに対して、2番目のものは約6000ミリ秒であることがわかります。なぜこれが起こったのか分かりません。なぜEigenコストで同じサイズの行列の内積が全く異なる時間ですか?

#include <iostream> 
#include <time.h> 

#include "Eigen/Dense" 

int main() { 
    clock_t start, stop; 

    Eigen::MatrixXf mat_a(1200, 1500); 
    Eigen::MatrixXf mat_b(1500, 1500); 
    Eigen::MatrixXf mat_r(1000, 1300); 
    int i, j; 
    float c = 0; 
    for (i = 0; i < 1200; i++) { 
     for (j = 0; j < 1500; j++) { 
      mat_a(i, j) = (float)(c/3 * 1.0e-40); 
      //if (i % 2 == 0 && j % 2 == 0) mat_a(i, j); 
      c++; 
     } 
    } 
    //std::cout << mat_a.row(0) << std::endl; 
    c = 100; 
    for (i = 0; i < 1500; i++) { 
     for (j = 0; j < 1500; j++) { 
      mat_b(i, j) = (float)(c/3 * 0.5e-10); 
      c++; 
     } 
    } 
    //std::cout << mat_b.row(0) << std::endl; 

    start = clock(); 
    mat_r = mat_a * mat_b; 
    stop = clock(); 
    std::cout << stop - start << std::endl; 
    getchar(); 
    return 0; 
} 

上記のコード例に示すとおりです。これは行列の値によって引き起こされることがわかります。これは、mat_aがe-40についての値を持ち、mat_bがe-10についての値を持つとき、この問題は安定して起こります。

説明できる人はいますか?

+1

EまたはFにNaN/Inf値が含まれているか、ベンチマークの方法に欠陥がある可能性があります。 – ggael

+0

この問題を再現するためのコードを追加しました。 b.t.w.、NaN/INFの問題はありません。 –

答えて

0

これは、CPUに対処するのが遅いdenormal numbersがマトリックスに含まれているためです。合理的な単位を使用して、ゼロと見なすことができるようにしてから、たとえば、高速数値モードを使用して、ゼロをフラッシングする(FTZ)フラグとゼロをゼロにするフラグ(DAZ)を有効にする必要がありますまたは実行時にthis SO questionを参照してください。

関連する問題