【问题标题】:Bottleneck in the Eigen partial_lu_inplace when factorizing a large number of small matrices分解大量小矩阵时,Eigen partial_lu_inplace 中的瓶颈
【发布时间】:2018-11-14 10:48:16
【问题描述】:

我需要分解 ~1e05 个最大 变量 大小为 20x20 的小矩阵。使用 HpcToolkit 分析矩阵分解显示代码中的热点位于 Eigen::internal::partial_lu_inplace

我检查了Eigen documenation on the inplace matrix decomposition,我了解大型矩阵使用就地分解、重用内存和提高缓存效率可能很重要。

我目前正在计算这样的分解:

// Factorize the matrix.
matrixFactorization_ = A_.partialPivLu(); 

使用HpcToolkit 进行分析表明原地分解是热点:

是否可以禁用就地分解并测试代码对于我正在处理的小矩阵是否会更快?

注意:如果您查看图像上列中的 CPU 时间,您会注意到运行时间以秒为单位:我这里没有经过微秒优化,计算总共需要大约 4 秒。

编辑:HPCToolkit 统计分析代码处于完全优化模式 -O3 ,但包含将测量映射到源代码-g3 所需的信息。

【问题讨论】:

    标签: eigen


    【解决方案1】:

    如果分析器为您提供了如此详细的信息,那么您忘记启用编译器的优化(例如,-O3 -march=native -DNDEBUG,或“发布”模式 + /arch:AVX 与 VS)。使用 Eigen,这将产生巨大的影响。

    那么您可以使用以下方法节省动态内存分配:

    typedef Matrix<double,Dynamic,Dynamic,ColMajor,20,20> MatMax20;
    MatMax20 A_;
    PartialPivLU<MatMax20> matrixFactorization_;
    

    矩阵A_PartialPivLU 的所有内部结构将因此被静态分配。

    为了更好地更新现有事实:

    matrixFactorization_.compute(A_);
    

    【讨论】:

    • 不,我已经在完全优化模式下编译,请参阅 HPCToolkit 文档。代码经过优化,但带有允许将统计测量映射到源代码的调试信息。
    • 另外,我有一个可变大小的矩阵,所以我无法在编译时固定大小,最大大小 20x20 只是为了提示系统大小。有没有一种简单的方法可以禁用 Eigen 中的就地操作?
    • ggael 建议的 typedef 确实为您提供了限制为 20x20 的动态大小矩阵。这避免了创建矩阵和 LU 分解时的动态分配。
    • @tmaric: "disable the inplace operations" -> 这没有意义,你看到的 partial_lu_inplace 函数是在内部计算 LU 分解的。这与您引用的文档关系不大。因此,除了我建议的优化之外,除了使用例如 openmp 并行计算多个分解之外,您无能为力。
    • @chtz:使用预初始化的最大矩阵大小,单元测试似乎运行得更快。使用-march=native 启用矢量化不会为较小的单元测试带来太多好处,我将使用此选项运行较大的测试,看看它是否有帮助。 @ggael:好的,明白了,谢谢帮助! @ggael:如果您删除了有关调试和优化标志的部分答案,我可以接受。修复最大矩阵大小有助于使测试运行得更快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-24
    • 1970-01-01
    • 2023-02-17
    • 1970-01-01
    • 2021-03-05
    相关资源
    最近更新 更多