2016-11-30 13 views
1

在追求最佳的矩陣的矩陣乘法矩陣,矩陣乘法性能問題,我寫了下面的測試:使用eigen3(和SIMD支持希望獲利),涉及MaxRowsAtCompileTime/MaxColsAtCompileTime

#include <iostream> 
#include <Eigen/Dense> 
#include <ctime> 

using namespace Eigen; 
using namespace std; 

const int test_size= 13; 
const int test_size_16b= test_size+1; 

typedef Matrix<double, Dynamic, Dynamic, ColMajor, test_size_16b,  test_size_16b> TestMatrix_dyn16b_t; 
typedef Matrix<double, Dynamic, Dynamic> TestMatrix_dynalloc_t; 
typedef Matrix<double, test_size, test_size> TestMatrix_t; 
typedef Matrix<double, test_size_16b, test_size_16b> TestMatrix_fix16b_t; 

template<typename TestMatrix_t> EIGEN_DONT_INLINE void test(const char * msg, int m_size= test_size, int n= 10000) { 
    double s= 0.0; 
    clock_t elapsed= 0; 
    TestMatrix_t m3; 
    for(int i= 0; i<n; i++) { 
     TestMatrix_t m1 = TestMatrix_t::Random(m_size, m_size); 
     TestMatrix_t m2= TestMatrix_t::Random(m_size, m_size); 

     clock_t begin = clock(); 
     m3.noalias()= m1*m2; 
     clock_t end = clock(); 
     elapsed+= end - begin; 

     // make sure m3 is not optimized away 
     s+= m3(1, 1); 
    } 

    double elapsed_secs = double(elapsed)/CLOCKS_PER_SEC; 
    cout << "Elapsed time " << msg << ": " << elapsed_secs << " size " << m3.cols() << ", " << m3.rows() << endl; 
} 

int main() { 
#ifdef EIGEN_VECTORIZE 
    cout << "EIGEN_VECTORIZE on " << endl; 
#endif 

    test<TestMatrix_t>   ("normal "); 
    test<TestMatrix_dyn16b_t> ("dyn 16b "); 
    test<TestMatrix_dynalloc_t>("dyn alloc"); 
    test<TestMatrix_fix16b_t> ("fix 16b ", test_size_16b); 
} 

g++ -msse3 -O2 -DEIGEN_DONT_PARALLELIZE test.cpp和編譯跑了上速龍II X2 255,結果使我頗感驚訝:

EIGEN_VECTORIZE on 
Elapsed time normal : 0.019193 size 13, 13 
Elapsed time dyn 16b : 0.025226 size 13, 13 
Elapsed time dyn alloc: 0.018648 size 13, 13 
Elapsed time fix 16b : 0.018221 size 14, 14 

類似的結果獲得與其他奇數號碼test_size。是什麼讓我困惑的是:

  • 從閱讀Eigen Vectorization FAQ我還以爲是一個13×13矩陣有沒有多16個字節的大小,因而不會從SIMD優化獲利。我預計計算時間會更糟,但事實並非如此。
  • 從閱讀約Optional template parameters我本來認爲動態矩陣與固定的上限在編譯時已知會表現就像動態分配矩陣的一個從而將具有類似的計算速度。但他們沒有。這實際上是什麼驚喜我最什麼觸發了我最初的追求:我想知道這是否是最好使用具有固定上限即是不是一個固定大小矩陣衛生組織的大小爲16個字節的倍數動態矩陣不是的倍數16個字節。
  • 最後有趣的,但沒有那麼多令人吃驚:一個矩陣衛生組織固定大小是16的倍數不慢於該衛生組織NcoI和行長度的矩陣的少一個。 SIMD只是免費的額外的col和row。
  • 不是我的問題,但也很有趣:當測試時無需矢量編譯沒有SSE2支持,因此相對的計算時間大致成正比。動態大小的固定存儲器矩陣再次最慢。

讓我的問題變得簡短:爲什麼Matrix<double, Dynamic, Dynamic, ColMajor, test_size_16b, test_size_16b>這麼慢?你能否證實我的觀察,甚至可以解釋他們?

回答

1

的FAQ已經過時。由於本徵3.3版本,未對齊的向量和矩陣量化。

那麼關於爲什麼Matrix<double, Dynamic, Dynamic, ColMajor, test_size_16b, test_size_16b>比較慢,這只是編譯時選擇首選矩陣產品實現的一個問題。該修復將成爲Eigen 3.3.1的一部分。