1

我在一个计算机图形项目中使用Eigen库,其网格会经常变化。

对所有顶点位置、法线等使用动态特征矩阵对性能有何影响?

我应该使用:

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

或者

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

每次更改后,我都必须将网格数据复制到 GPU,但据我了解,我可以使用 memcpy 有效地使用两种表示形式进行此操作。

4

3 回答 3

3

Vector 可能会消耗更多内存,因为它通常分配的空间比存储数据所需的空间多,并且Eigen::Vector3f每次调整它的大小时,vector 都会调用默认构造函数和析构函数。AFAIK,默认Eigen::Vector3f构造函数是空的,因此在发布构建中花费为零(但由于这个和调试迭代​​器,您可能会在调试构建中遇到性能问题)。另一方面,Eigen::Matrix每次调整大小时都会重新分配内存(它也会复制内容,就像std::vector你使用conservativeResize一样),这很慢。

但是,我还是推荐你使用vector,因为它更方便。您可以动态添加元素,无需重新分配即可调整其大小,在矢量上使用标准算法更简单。如果你想确定你的向量不会消耗比需要更多的内存,你可以使用这个技巧来调整它的大小:

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

或查看shrink_to_fit

是的,您可以使用 memcpy 使用这两种表示有效地复制数据。但是 usingstd::copy将在发布版本中以相同的性能完成相同的工作(有时它甚至被编译器替换为memcpy)。

但是,如果您仍然对性能不满意,以下是我为自己制定的在这种情况下做出决定的提示:

  • 如果您要经常调整顶点数组的大小(添加或删除元素)->std::vector避免频繁的重新分配。
  • 如果您将大量数据存储在顶点数组中->Eigen::Matrix避免过多的内存消耗。
  • 如果您对调试模式下的性能不满意(如果您经常处理顶点数组中的数据,这将是幸运的)-> go with Eigen::Matrixstl调试迭代器可能会破坏性能(仅适用于 MSVC)

还可以考虑boost::shared_array (scoped_array),它们是专门为存储大块数据而不消耗额外内存而设计的。在您的场景中使用它们更有意义。

于 2012-12-08T17:03:28.837 回答
1

动态分配的矩阵数组通常存在两个问题:

  • 您将无法使用全局memcpy来复制整个结构:在动态分配矩阵的情况下(例如,您有 anstd::vector<float*>而不是 an std::vector<Eigen::Vector3f>),您的数组仅包含一系列指针,并且所有这些指针都可以指向到内存中非常不同的位置。因此,执行 amemcpy只会复制指针,而不是数据,并且无法更改它,因为您的元素在内存中不是连续的(只有它们的指针是)。相反,您需要遍历 的每个元素,分别使用和元素std::vector访问它。例如,在执行 your 时,您将拥有(或类似的东西:它存储一个指针和许多行和列),而operator[]memcpymemcpysizeof(Eigen::Matrix<float, Eigen::Dynamic, 3, Eigen::RowMajor>) = sizeof(void*) + 2*sizeof(int)sizeof(Eigen::Vector3f) = 3*sizeof(float)因为它真正存储数据而不是指针。

  • 如果您需要频繁地创建和销毁矩阵,则使用动态分配的矩阵执行此操作会慢得多。具有固定大小的矩阵允许在堆栈上进行分配,这使其更快。

于 2012-12-06T07:33:11.623 回答
1

两种表示的内存布局完全相同。主要区别在于,如果您需要插入向量或类似的东西, std::vector<> 会更加灵活。另一方面 Matrix<.,3,Dynamic> 是一个 Eigen 对象,因此更容易对其执行一些操作,例如:

Matrix<.,3,Dynamic> data;
data = Affine3f(...) * data; // apply an affine transformation
data.colwise().norm(); // get the norm of each vectors
...
于 2012-12-09T08:57:13.477 回答