本征动态大小矩阵的 C++ 数组
C++ array of Eigen dynamically sized matrix
在我的应用程序中,我有一个一维网格,每个网格点都有一个矩阵(大小相等且为二次矩阵)。对于每个矩阵,必须执行特定的更新过程。目前,我定义了一个类型
typedef Eigen::Matrix<double, N, N> my_matrix_t;
并使用
为所有网格点分配矩阵
my_matrix_t *matrices = new my_matrix_t[num_gridpoints];
现在我想解决大小仅在 运行 时间已知(但仍然是二次方)的矩阵,即
typedef Eigen::Matrix<double, Dynamic, Dynamic> my_matrix_t;
分配过程保持不变,代码似乎有效。但是,我假设数组 "matrices" 只包含指向每个单独矩阵存储的指针,并且整体性能会降低,因为在对每个矩阵执行操作之前必须从随机位置收集内存。
Q0:连续内存?
假设正确吗
- new[]只会存储指针,矩阵数据存储在head的任意位置?
- 对于此类问题有一个连续的内存区域是有益的吗?
Q1:新[]还是std::vector?
评论中建议使用 std::vector。这有什么区别吗? Advantages/drawbacks 两种解决方案?
问题 2:重载 new[]?
我认为通过在 Eigen::Matrix class(或其基数之一)中重载 operator new[] 可以实现这样的分配。这是个好主意吗?
Q3:替代方法?
作为替代方案,我可以考虑使用大 Eigen::Matrix。任何人都可以在这里分享他们的经验吗?您对我还有其他建议吗?
让我们根据对问题的评论和邮件列表 post here 总结一下我们目前的情况。我想鼓励大家编辑和添加东西。
Q0:连续内存区域。
- 是的,只存储指针(独立于使用 new[] 或 std::vector)。
- 通常,在 HPC 应用程序中,连续内存访问是有益的。
Q1:基本机制是一样的
但是,std::vector 提供了更多的舒适感并减轻了开发人员的工作量。后者还减少了错误和内存泄漏。
Q2:使用std::vector.
不推荐重载 new[],因为很难做到正确。例如,对齐问题可能导致不同机器上的错误。为了保证在所有机器上的正确行为,使用
std::vector<my_matrix_t, Eigen::aligned_allocator<my_matrix_t>> storage;
解释为 here。
Q3:对完整的网格使用大的特征矩阵。
或者,让 Eigen 库直接使用其数据结构进行完整分配。这保证了对齐和连续内存区域等问题得到正确解决。矩阵
Eigen::Matrix<double, Dynamic, Dynamic> storage(N, num_grid_points * N);
包含完整网格的所有矩阵,可以使用
寻址
/* i + 1 'th matrix for i in [0, num_gridpoints - 1] */
auto matrix = storage.block(0, i * N, N, N);
在我的应用程序中,我有一个一维网格,每个网格点都有一个矩阵(大小相等且为二次矩阵)。对于每个矩阵,必须执行特定的更新过程。目前,我定义了一个类型
typedef Eigen::Matrix<double, N, N> my_matrix_t;
并使用
为所有网格点分配矩阵my_matrix_t *matrices = new my_matrix_t[num_gridpoints];
现在我想解决大小仅在 运行 时间已知(但仍然是二次方)的矩阵,即
typedef Eigen::Matrix<double, Dynamic, Dynamic> my_matrix_t;
分配过程保持不变,代码似乎有效。但是,我假设数组 "matrices" 只包含指向每个单独矩阵存储的指针,并且整体性能会降低,因为在对每个矩阵执行操作之前必须从随机位置收集内存。
Q0:连续内存?
假设正确吗
- new[]只会存储指针,矩阵数据存储在head的任意位置?
- 对于此类问题有一个连续的内存区域是有益的吗?
Q1:新[]还是std::vector?
评论中建议使用 std::vector。这有什么区别吗? Advantages/drawbacks 两种解决方案?
问题 2:重载 new[]?
我认为通过在 Eigen::Matrix class(或其基数之一)中重载 operator new[] 可以实现这样的分配。这是个好主意吗?
Q3:替代方法?
作为替代方案,我可以考虑使用大 Eigen::Matrix。任何人都可以在这里分享他们的经验吗?您对我还有其他建议吗?
让我们根据对问题的评论和邮件列表 post here 总结一下我们目前的情况。我想鼓励大家编辑和添加东西。
Q0:连续内存区域。
- 是的,只存储指针(独立于使用 new[] 或 std::vector)。
- 通常,在 HPC 应用程序中,连续内存访问是有益的。
Q1:基本机制是一样的
但是,std::vector 提供了更多的舒适感并减轻了开发人员的工作量。后者还减少了错误和内存泄漏。
Q2:使用std::vector.
不推荐重载 new[],因为很难做到正确。例如,对齐问题可能导致不同机器上的错误。为了保证在所有机器上的正确行为,使用
std::vector<my_matrix_t, Eigen::aligned_allocator<my_matrix_t>> storage;
解释为 here。
Q3:对完整的网格使用大的特征矩阵。
或者,让 Eigen 库直接使用其数据结构进行完整分配。这保证了对齐和连续内存区域等问题得到正确解决。矩阵
Eigen::Matrix<double, Dynamic, Dynamic> storage(N, num_grid_points * N);
包含完整网格的所有矩阵,可以使用
寻址/* i + 1 'th matrix for i in [0, num_gridpoints - 1] */
auto matrix = storage.block(0, i * N, N, N);