【C++】Eigen优化及D8016错误

2023-05-16

Eigen优化过程

背景

最近在写一个保边滤波的算法。为了加快运算速率,采用C++语言,使用Eigen库进行大矩阵运算。

效率问题

作为基于全局图像的算法,需要创建一个全局的矩阵(n*m在数千万到数亿的级别),但是,有效数据大约只有数十万级别,也就是说这是一个不折不扣的稀疏矩阵。因此,我们所有的矩阵运算都是基于Eigen::SparseMatrix

对于矩阵的构建,常用的有以下几种方法。

  • 直接给稀疏矩阵(SparseMatrix赋值)

    Eigen::SparseMatrix<double> sparse(rows,cols);
    sparse.insert(row, col, num);  //如果数据不存在 
    sparse.coeffRef(row,col,num);  //如果数据已经存在
    

    经过测试,在没有数据的情况下,insert()coeffRef(),不论从效率上,还是从效果上,基本没有什么大的差别。

    在实际运行过程中,这种写法是效率最差的一种。20W+的数据跑了1分钟没出结果,果断停了。我们是要做到毫秒级的!!!

  • 使用三元组初始化稀疏矩阵

    typename Eigen::Triplet<double> TD;
    vector<TD> tripletList;
    tripletList.reserve(N);
    for(int i=0;i<N;i++;){
        tripletList.push_bach(TD(row,col,num));   //push 操作效率低的离谱
    }
    Eigen::SparseMatrix<double> sparse(rows,cols);
    sparse.setFromTriplet(tripletList.begin(),tripletList.end());  // 这就是为什么我不喜欢用vector,又不得不用的原因
    if(!m_sparseB.isCompressed())   //判断是否有多余的空间需要压缩
    	m_sparseB.makeCompressed();
    

    代码简洁明了,不多做解释。

    在实际运行过程中,这种官方推荐,且被大量使用的写法,效率上依旧是不能满意(20W+的数据,跑7S)。接下来,我们深入探究一下这个原因。

探究及优化

  • vector::push_back()是个性能非常的差。

    void fVector() {    //0.413247
        vector<int> vec;
        for (size_t i = 0; i < 2000000; i++) {
            vec.push_back(i);
        }
    }
    void fvecSize() {   //0.0406735
        vector<int> vec(2000000);
        for (size_t i = 0; i < 2000000; i++) {
            vec[i] = i;
        }
    }
    void farray() {   //0.0091637
        int* vec = new int[2000000];
        for (size_t i = 0; i < 2000000; i++) {
            vec[i] = i;
        }
        delete[] vec;
    }
    
    
    1. 在实际测试中,200W的数据,跑出了0.4s,的成绩。

    2. 提前分配内存,使用 = 操作,时间消耗只有0.04s。性能差了10倍!!!

    3. 直接使用数组,则只需要0.009s

    综上:我要干掉push操作

  • setFromTriplet是需要编译器优化的

    干掉push之后,效率问题依旧没有得到明显的改变。经过分析,setFromTriplet跑了6S+,我再一次陷入沉思。因为,同样的逻辑,大兄弟跑出了1.3s的骄人成绩。他还是做了大量矩阵计算的前提下,而我,只是得到了两个矩阵,还没有进行计算。

    经过我虚心请教,得到两个可以极大提升效率的优化操作:

    1. 开启VS的优化设置

      项目属性
      C/C++
      优化

      根据自己需要,选择时间优先,或者空间优先。

      选择之后,需要关闭编译时的检查,否则会D8016报错。

      项目属性
      C/C++
      代码生成
      基本运行时检查

      把运行时检查选为默认值即可。

    2. 用release跑

      在我跑的代码中,release版本比debug 效率提升大概4倍左右。

VS D8016

D8016 “/Ox”和“/RTC1”命令行选项不兼容

关于该错误,详细了解可看官方文档

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++】Eigen优化及D8016错误 的相关文章

  • 将 Eigen 库与 OpenCV 2.3.1 结合使用

    我使用时遇到问题Eigen3图书馆连同OpenCV应用在C 我已经使用以下命令在 Ubuntu 上安装了 Eigen3 库 sudo apt get install libeigen3 dev 我能够编译和使用Eigen3 应用程序示例 E
  • Eigen3 根据列条件选择行

    我的特征矩阵有一个二维矩阵 例如 122 443 544 456 0 9 324 435 5465 645 0 8 32 434 545 546 0 778 435 546 6565 656 0 6878 546 6565 656 3453
  • 如何使用OpenCV进行LU分解?

    cvInvert 方法采用标志 CV LU 进行 LU 分解以反转输入矩阵 但是有什么方法可以获得计算过程中形成的 L 和 U 矩阵吗 为 LU 分解编写一个新函数似乎毫无意义 因为 OpenCV 已经为其优化了代码 不幸的是 OpenCV
  • eigen 是否有像 H.transpose()*H 这样的自转置乘法优化

    我浏览过 eigen 的教程https eigen tuxfamily org dox devel group TutorialMatrixArithmetic html 它说 注意 对于担心性能的 BLAS 用户 c noalias 2
  • 在 Apple M1 上使用 clang 出现“致命错误:找不到‘omp.h’文件”

    Clang 找不到omp h每当我尝试使用 openMP 标志进行编译时 这就是我想做的 clang dynamiclib I opt homebrew Cellar eigen 3 3 9 include eigen3 Xpreproce
  • 在 MEX 函数中将特征复数矩阵返回到 MATLAB,无需额外复制

    这个问题演示如何使用映射对象将双精度矩阵返回到 MATLAB 以下适用于非复杂数据 double outputPtr plhs 0 mxCreateDoubleMatrix mwSize n mwSize m mxREAL outputPt
  • std::vector 的对齐问题

    我终于遇到了这里描述的烦人的问题 https eigen tuxfamily org dox group TopicStlContainers html 我有一个包含多个特征固定大小矩阵的结构 并且我想将结构的多个实例存储在 std vec
  • 稠密对称矩阵的特征有效类型

    Does Eigen http eigen tuxfamily org index php title Main Page有存储密集 固定大小 对称矩阵的有效类型吗 嘿 它们无处不在 IE 对于 N 9 它应该只存储 1 9 9 2 45
  • eigen3 与 libfmt >= 9.0

    我曾经能够将 Eigen3 数组 矩阵传递给 spdlog 它内部使用 libfmt 从 libfmt 9 0 0 开始 这些类型不再由 libfmt 格式化 无需进一步的代码 fmt 通过专门化支持自定义类型fmt formatter
  • 在 Android 中使用 iBeacons 进行三边测量

    我们希望使用 iBeacons 实现某种室内位置确定 这篇文章看起来真的很有趣 http techblog rga com determining indoor position using ibeacon 其中作者使用 Eigen C 库
  • 如何复制特征矩阵

    我有两个Eigen MatrixXd他们总是有一排 输入矩阵是A我想将这个矩阵复制到另一个矩阵中B 但矩阵之间的列数可以不同 下面是一个例子 A 0 5 我需要创建一个B1行4列的矩阵 因此它是 B 0 5 0 5 0 5 0 5 But
  • Eigen:返回对带有编译时维度检查的矩阵块的引用

    我要问的是一个概括这个问题 https stackoverflow com questions 13548253 eigen library return a matrix block in a function as lvalue 具体来
  • C++ 对齐的未来:按值传递?

    阅读 Eigen 库文档 我注意到有些对象不能按值传递 http eigen tuxfamily org dox TopicPassingByValue html C 11 中是否有任何开发或计划开发可以安全地按值传递此类对象 另外 为什么
  • 查找 CMake 的包 Eigen3

    CMake 找不到我的Eigen3包裹 我设置了一个名为的环境变量 EIGEN3 INCLUDE DIR 指向路径所在的位置FindEigen3 cmake is 然后在 CMakelists txt 中我写道 find package E
  • cygwin_exception::open_stackdumpfile:将堆栈跟踪转储到 *.exe.stackdump

    我收到 cygwin exception open stackdumpfile 将堆栈跟踪转储到 TestProject exe stackdump 错误 我的项目只不过是一个 C HalloWorld 项目 其中包含一个附加类 我在其中设
  • 特征密集稀疏矩阵乘积是线程化的吗?

    我知道稀疏密集产品是根据文档进行线程化的 https eigen tuxfamily org dox TopicMultiThreading html https eigen tuxfamily org dox TopicMultiThre
  • 从模板类创建对象时出错

    我一直在尝试找到一种方法 从 C 中的多元正态分布中采样随机向量 同时具有均值向量和协方差矩阵 就像 Matlab 的那样mvnrnd功能有效 我找到了实现此功能的类的相关代码这一页 http lost found wandering bl
  • Eigen 中的元素最大值和正部分

    我想在特征中取两个向量 矩阵的元素最大值 到目前为止 我已经编写了这段代码 template
  • 将标量添加到特征矩阵(向量)

    我刚刚开始使用 Eigen 库 无法理解如何向所有矩阵成员添加标量值 假设我有一个矩阵 Eigen Matrix3Xf mtx Eigen Matrix3Xf Ones 3 4 mtx mtx 1 main cxx 104 13 error
  • 模板成员函数和 std::invocable 的 C++20 概念中的错误

    我正在尝试 C 20 概念和本征库 https eigen tuxfamily org index php title Main Page 我发生了意想不到的行为 具体来说 考虑以下概念 要求类型可以通过以下任一方式调用 Eigen Mat

随机推荐