2017-07-24 407 views
3

在我的項目中,我使用Eigen3.3庫來計算6x6矩陣。我決定調查AVX指令是否真的讓我對SSE有任何加速。我的CPU不支持兩組:對於單精度矩陣運算,特徵性能AVX與SSE沒有差別?

model name  : Intel(R) Xeon(R) CPU E5-1607 v2 @ 3.00GHz 
flags   : ... sse sse2 ... ssse3 ... sse4_1 sse4_2 ... avx ... 

所以,我編譯gcc4.8如下所示一個小的測試使用兩套不同的標誌:

$ g++ test-eigen.cxx -o test-eigen -march=native -O2 -mavx 
$ g++ test-eigen.cxx -o test-eigen -march=native -O2 -mno-avx 

我證實,與-mno-avx第二種情況下做不會產生任何使用ymm寄存器的指令。儘管如此,這兩起案件給我的結果非常相似,約爲520ms,用perf來衡量。

下面是程序測試eigen.cxx(它兩個矩陣的總和的倒數只是爲了接近實際任務我的工作):

#define NDEBUG 

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

using namespace Eigen; 

int main() 
{ 
    typedef Matrix<float, 6, 6> MyMatrix_t; 

    MyMatrix_t A = MyMatrix_t::Random(); 
    MyMatrix_t B = MyMatrix_t::Random(); 
    MyMatrix_t C = MyMatrix_t::Zero(); 
    MyMatrix_t D = MyMatrix_t::Zero(); 
    MyMatrix_t E = MyMatrix_t::Constant(0.001); 

    // Make A and B symmetric positive definite matrices 
    A.diagonal() = A.diagonal().cwiseAbs(); 
    A.noalias() = MyMatrix_t(A.triangularView<Lower>()) * MyMatrix_t(A.triangularView<Lower>()).transpose(); 

    B.diagonal() = B.diagonal().cwiseAbs(); 
    B.noalias() = MyMatrix_t(B.triangularView<Lower>()) * MyMatrix_t(B.triangularView<Lower>()).transpose(); 

    for (int i = 0; i < 1000000; i++) 
    { 
     // Calculate C = (A + B)^-1 
     C = (A + B).llt().solve(MyMatrix_t::Identity()); 

     D += C; 

     // Somehow modify A and B so they remain symmetric 
     A += B; 
     B += E; 
    } 

    std::cout << D << "\n"; 

    return 0; 
} 

如果我真的期待更好AVX在Eigen中表現如何?或者我在編譯器標誌或特徵配置中丟失了一些東西?我的測試可能不適合證明不同之處,但我沒有看到它可能有什麼問題。

+0

我不知道Eigen還支持AVX。實際上它甚至現在支持AVX512。很高興知道http://eigen.tuxfamily.org/index.php?title=3.3#Vectorization。 –

回答

5

您正在使用過小的矩陣來使用AVX:單精度AVX一次可以處理8個標量的數據包。當使用6x6矩陣時,AVX只能用於像A = B + C這樣純粹的組件式操作,因爲它們可以被看作是對大小爲36的一維向量的操作,大小爲8。在你的情況下,這些操作可以忽略不計, Cholesky分解和解決的費用。

要查看差異,請移至MatrixXf大小爲100x100或更大的矩陣。