2012-12-05 80 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

相关问题