2014-12-02 34 views
1

我想包裝Eigen3線性代數庫,使其語法變得更乾淨。然而,作爲第一步,當我創建+運算符重載(通過+ =重載)時,包裝立即遭受3次性能損失。你能否提供一些有關事情出錯和如何解決的見解?謝謝。庫適配器性能損失

#include <iostream> 
#include <ctime> 
using namespace std; 
#include "Eigen\Eigen" 

class Wmat 
{ 
    Eigen::ArrayXXd M; 
public: 
    Wmat& operator+=(const Wmat& rhs) 
     {this->M += rhs.M; return *this;} 
    const Wmat operator+(const Wmat &rhs2) 
     {Wmat result = *this; result+= rhs2; return result;} 
    void Random(int D1, int D2) 
     {M = Eigen::ArrayXXd::Random(D1,D2);} 
}; 

int main() 
{ 
    int D = 1000000; 
    int T=1000; 
    clock_t start; 
//--------------------------------------------------------------- 
    Eigen::ArrayXXd LHS = Eigen::ArrayXXd::Random(D,1); 
    Eigen::ArrayXXd RHS1 = Eigen::ArrayXXd::Random(D,1); 
    Eigen::ArrayXXd RHS2 = Eigen::ArrayXXd::Random(D,1); 
    start = clock(); 
    for (int i=1; i<=T; ++i) 
    { 
     LHS = RHS1 + RHS2; 
    } 
    cout << (clock()-start)/(double) CLOCKS_PER_SEC << endl; 
//--------------------------------------------------------------- 
    Wmat LHSW, RHSW1, RHSW2; 
    RHSW1.Random(D,1); RHSW2.Random(D,1); LHSW.Random(D,1); 
    start = clock(); 
    for (int i=1; i<=T; ++i) 
    { 
     LHSW = RHSW1 + RHSW2; 
    } 
    cout << (clock()-start)/(double) CLOCKS_PER_SEC << endl; 
//--------------------------------------------------------------- 
    return 0; 
} 
+1

您是否計時優化版本或未優化的「調試」版本? – PaulMcKenzie 2014-12-02 19:53:56

+0

如果我正確理解你的問題,我在發佈版本下運行直接Eigen3和包裝Eigen3。謝謝。 – AndreasBVB 2014-12-02 20:00:36

+3

也許Eigen庫在避免複製方面更好一些?例如,'RHSW1 + RHSW2'實際上並不需要創建一個新的矩陣,只需要創建一個對象來存儲對這兩個操作數的引用,並且在分配給一個矩陣時,它將評估表達式並將其存儲在目標。這種技術可以大大提高速度。也就是說,使用一個分析器來找出時間花在哪裏。另外,請考慮Eigen開發人員在性能可讀性方面的可能性。 – 2014-12-02 20:00:38

回答

1

寫入包裝將無法使用表達式模板。例如,您在Wmat中添加的任何方法將不可用於a+b,除非您在Wmat內明確評估它,因此失去了Eigen的大部分功能。使其與舊的矩陣/矢量庫兼容的正確方法是利用Eigen的插件機制。該機制允許直接在Eigen的對象和表達式的類定義內添加新成員。有關詳細信息,請參見page