2017-07-24 47 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或更大的矩阵。