2012-12-05 79 views
1

我在計算機圖形項目中使用Eigen庫,網格經常變化。使用Eigen的網格:MatrixX3f或std :: vector <Vector3f>?

什麼是使用動態特徵矩陣爲所有的頂點位置,法線等對性能的影響?

我應該使用:

Eigen::Matrix<float, Eigen::Dynamic, 3, Eigen::RowMajor> vertices; 

std::vector<Eigen::Vector3f> vertices; 

我會在每次更改後的網格數據複製到GPU,但據我瞭解,我可以做到這一點的memcpy高效與這兩個表示。

回答

1

這兩種表示的內存佈局完全相同。主要區別在於,如果您需要插入向量或類似的東西,std :: vector <>會更加靈活。 。在另一方面矩陣<,3,動態>是本徵對象,因此它更容易對其執行一些操作,例如:

Matrix<.,3,Dynamic> data; 
data = Affine3f(...) * data; // apply an affine transformation 
data.colwise().norm(); // get the norm of each vectors 
... 
1

兩個問題一般與動態分配的矩陣陣列:

  • ,你將無法使用全局memcpy來複制你的整個結構:在動態分配矩陣的情況下(例如,你有一個std::vector<float*>而不是一個std::vector<Eigen::Vector3f>),你的數組只包含一系列指針,所有這些指針可以指向內存中非常不同的位置。因此,執行memcpy將只複製指針,而不是數據,並且無法更改,因爲您的元素在內存中不連續(只有它們的指針)。相反,您需要瀏覽您的std::vector中的每個元素,分別使用operator[]memcpy訪問它。例如,做你memcpy時,你將有sizeof(Eigen::Matrix<float, Eigen::Dynamic, 3, Eigen::RowMajor>) = sizeof(void*) + 2*sizeof(int)(或類似的東西:它存儲指針和行數和列),而sizeof(Eigen::Vector3f) = 3*sizeof(float)因爲它確實存儲數據,而不是指針。

  • ,如果你需要頻繁創建和銷燬矩陣,這樣做與動態分配的矩陣就會慢很多。具有固定大小的矩陣允許在堆棧上進行分配,這使得它更快。

3

矢量可能會消耗更多的內存,因爲它通常分配給存儲數據和矢量每次都會調用默認的構造函數和析構函數爲Eigen::Vector3f你調整它的大小比需要更多的空間。 AFAIK,默認Eigen::Vector3f構造函數是空的,所以它會在發佈版本中花費你零(但是由於這個和調試迭代​​器,你可能在調試版本中遇到性能問題)。在另一邊,Eigen::Matrix將每次調整其大小(它也將內容複製,就像std::vector如果你使用conservativeResize)時重新分配內存,這是緩慢的。

Howewer,我還是建議你使用矢量,因爲它更方便。您可以動態添加元素,調整其大小而不重新分配,在矢量上使用標準算法會更簡單。如果你想可以肯定,你的載體不消耗比需要更多的內存,你可以用這種伎倆來調整它的大小:

std::vector<Eigen::Vector3f> vertices; 
vertices.swap(std::vector<Eigen::Vector3f>(size, Eigen::Vector3f())); 

還是看shrink_to_fit

是的,你可以使用memcpy複製數據有效地使用這兩種表示。但使用std::copy將在發佈版本中以相同的性能完成相同的工作(有時它甚至被具有memcpy的編譯器取代)。

Howewer,如果你還是不滿意的表現,這裏有技巧我做了爲自己做出在這種情況下的決定:

  • 如果你要頻繁調整頂點數組(或添加刪除元素) - >用std::vector去避免頻繁重新分配。
  • 如果在頂點數組中存儲大量數據塊 - >請使用Eigen::Matrix以避免過多的內存消耗。
  • 如果你不滿足於在調試模式下的表現(這將幸好是真實的,如果你經常在你的頂點數組處理數據) - >去Eigen::Matrixstl調試迭代器可以毀掉性能(僅適用於MSVC真)

也可以考慮boost::shared_array(scoped_array),它們專門用來存儲大塊數據而不消耗額外的內存。在你的場景中使用它們更有意義。

+1

這個答案含有很好的提示;不幸的是,我只能接受一個答案。 – Wilbert

相關問題