2010-05-20 53 views
1

我正在尋找一個二維矩陣(或位圖)類,它是靈活的,但也快速元素訪問。內容的靈活類應該允許你選擇在運行時的尺寸,而且會是這個樣子(簡化):C++矩陣/位圖類的優化

class Matrix 
{ 
public: 
    Matrix(int w, int h) : 
    data(new int[x*y]), width(w) {} 

void SetElement(int x, int y, int val) 
{ 
    data[x+y*width] = val; 
} 

// ... 
private: // symbols 
    int width; 
    int* data; 
}; 

使用模板更快經常提出的解決方案(簡化):

template <int W, int H> 
class TMatrix { 
    TMatrix() data(new int[W*H]) {} 

    void SetElement(int x, int y, int val) 
    { 
    data[x+y*W] = val; 
    } 

    private: 
    int* data; 
}; 

由於寬度可以在代碼中「內聯」,因此速度更快。第一個解決方案不這樣做。然而,這不是很靈活,因爲你不能在運行時改變大小。

所以我的問題是: 有沒有可能告訴編譯器生成更快的代碼(如使用模板解決方案時),當代碼中的大小是固定的,並在運行時依賴代碼時生成靈活的代碼?

我試圖通過在任何可能的地方寫「const」來實現這一點。我用gcc和VS2005試了一下,但沒有成功。這種優化對於許多其他類似的情況是有用的。

+0

「這種優化方式對許多其他類似情況很有用。」你是基於實際測試還是僅僅基於你的信念來說這個?請記住,不成熟的優化和所有這一切。 – 2010-05-20 23:23:47

+0

你是否分析了這段代碼?對於任何未嵌入的內容,額外的乘法和相加甚至不會出現在perf中。在許多平臺上使用硬件向量數學支持和/或批量複製值而不是一次一個地獲取數據將比贏得兩個標量操作更多的勝利。 – 2010-05-20 23:28:52

回答

0

我只想跟第一個版本,我自己。但是,如果你真的想試圖獲得兩全其美的好處,你可以有一個Matrix類,它持有一個指向多態實現類型的指針。對於常見大小(比如4x4),您可以指向模板實例化,對於更大的指向,可以指向處理一般MxN大小寫的實現。說了這麼多,我認爲虛擬調用的所有間接&都會否定可能來自模板的任何性能改進。在這種情況下,我不認爲你可以吃你的蛋糕&。

如果你總是在編譯時處理大小已知的數據(例如圖形/幾何向量),那麼最好使用模板版本(可能將數據存儲爲靜態大小(非堆分配) )數組)。如果您需要任意數據的通用功能,請改用動態版本。

0

當然您的需求可能會有所不同,但我會跳過自動生成,只是簡單地使用一組簡單的「固定」版本。例如。 Vector3,Vector4,Matrix3x3,Matrix3x4和Matrix4x4。我想你可以從模板版本中獲得所有這些,但它不會產生任何特定的性能差異。

有沒有什麼特別的原因讓你想在運行時改變尺寸?因爲我認爲只需要從一個拷貝到另一個拷貝對於需要發生變化的情況(我懷疑是罕見的情況)來說不會非常昂貴。

最後 - 我見過的東西是具有命名元素訪問以及數組,但只能用「硬編碼」類型來完成。喜歡的東西:

class Vector3 
{ 
public: 
    // other stuff... 

    union 
    { 
     struct { float x, y, z; }; 
     float m[3]; 
    }; 
}; 

(可能不完全合法的C++,謬以滿足您的編譯器)

哦,連模板版本並不需要用新的。只需將數據聲明爲float data[W*H];將它從堆中取出將比「優化」一些數學方法更大的性能提升。

0

與其說是完整的答案,但一些信息,可以幫助(如果你不是已經知道了這些):兩個OpenCVBoost (uBLAS)有很好的(快速/完整/全功能)矩陣實現。我沒有看到他們看到他們如何設置/獲取元素或在實例化後調整大小。