C++ 为什么要使用第三方向量库?

C++ 为什么要使用第三方向量库?,c++,arrays,eigen,C++,Arrays,Eigen,所以我想在我正在做的一个项目中使用特征矩阵库(2D空间模拟器)。我只是继续用Egeng::Vector2d和裸数组分析了一些代码。我注意到数组中的元素赋值提高了10倍,点积计算提高了40倍 如果你想看看的话,这里基本上是~4.065秒对~0.110秒 显然,裸阵列在点积和赋值方面效率更高。那么为什么要使用Eigen库(或者任何其他库,Eigen似乎是最快的)?是稳定吗?复杂的数学很难自己高效地编写?这些图书馆的真正优势在于内置的SIMD矢量化 默认情况下,eigen似乎没有启用该功能,您需要使用

所以我想在我正在做的一个项目中使用特征矩阵库(2D空间模拟器)。我只是继续用Egeng::Vector2d和裸数组分析了一些代码。我注意到数组中的元素赋值提高了10倍,点积计算提高了40倍

如果你想看看的话,这里基本上是~4.065秒对~0.110秒


显然,裸阵列在点积和赋值方面效率更高。那么为什么要使用Eigen库(或者任何其他库,Eigen似乎是最快的)?是稳定吗?复杂的数学很难自己高效地编写?

这些图书馆的真正优势在于内置的SIMD矢量化

默认情况下,eigen似乎没有启用该功能,您需要使用define/compiler开关。(编辑:误读链接,如果检测到编译器支持该链接,则会启用该链接,并且您需要启用某些编译器上的指令,但是,默认情况下,编译器上的指令可能会启用,也可能不会启用)


(更不用说,它们通常比自制的解决方案经过更彻底的测试,并且能够实现各种复杂/有趣的东西,这是手工编写代码的真正负担)

选择标准库代码有很多原因

  • 更好的可移植性。单个开发人员可能没有考虑(或可能没有访问)多个平台
  • 更好的可靠性。(正如唐尼所提到的)图书馆通常会经过更彻底的测试
  • 更好的开发人员移动性。如果其他人使用标准库组件,那么他们的代码更容易处理
  • 避免重新发明轮子。您希望避免每个开发人员以自己的方式开发相同组件的情况
  • 自定义实现很快就会过时。在有限的时间内,您可以不断更新和支持您的库版本。标准库可能会有更多的支持工作
  • 更好的“外部”支持。例如,考虑C++ STL库。您将从非原始开发人员那里找到大量资源。此外,教科书将涵盖标准库组件,这有助于新用户和学生学习它们,而不会给开发人员带来任何负担

PS/免责声明:抱歉,我不知道Eigen库。以上几点是关于标准库的更一般的观点。

我刚刚查看了您的基准测试,得到了以下结果:

g++ -I/usr/include/eigen3/ eigen.cpp -o eigen
g++ -O3 -I/usr/include/eigen3/ eigen.cpp -o eigen_opt
g++ -I/usr/include/eigen3/ matrix.cpp -o matrix
g++ -O3 -I/usr/include/eigen3/ matrix.cpp -o matrix_opt

./eigen  3.10s user 0.00s system 99% cpu 3.112 total
./eigen_opt  0.00s user 0.00s system 0% cpu 0.001 total
./matrix  0.06s user 0.00s system 96% cpu 0.058 total
./matrix_opt  0.00s user 0.00s system 0% cpu 0.001 total
除非打开编译器优化,否则Eigen真的不快。我还怀疑
-O3
案例中的编译器进行了一些针对基准字符的优化。你可能想调查一下


我认为这消除了你不使用库的一个要点:速度。一旦这些标准被排除在外,我就没有理由不使用现有的图书馆,除非你想为学术目的做点什么,或者你想写你自己的图书馆。现在,每当我看到一个实现自己的矩阵和向量类的库或其他代码时,如果可能的话,我都会尽量避免使用它。有了Eigen,我对Matlab的需求甚至更低了…

这是你的项目,随你的便。Eigen的时间似乎非常缓慢。你用什么命令行选项编译它?-g,我想是-O2,不过我只是读了更多,显然用-DEIGEN_NO__DEBUG编译加快了一点编辑速度:根据它从10x到30x的速度,这些库的一个更大的胜利是使用像表达式模板这样的东西来加速表达式,比如
a*b+(c*d)
通过删除任何临时分配并展开到单个循环中。根据我所能告诉您的,进行了快速的维基百科查找SIMD只允许对向量执行并行操作(如果我错了,请纠正我)。然而,我只是在简单的应用程序中使用向量,主要是点积。您是否在考虑更多与编程相关的bear编码?SIMD通过在一条指令中对多个数据段执行相同操作来加快操作速度。在这种情况下,“矢量化”是并行计算的意思,它在对矢量(数学实体)进行计算时有用途,但不仅仅与它们相关。然而,你是对的,整体的胜利在很大程度上取决于你实际做了什么,启用SIMD的库有时是完全多余的(尽管你仍然有它已经调试过的好处)@Yuushi事实上,eigen站点有一个关于eigen矩阵/类如何巧妙地分配临时变量的部分,因为它将选择删除temp是否是理想的,所以在分析此代码时将非常非常小心:不会使用点积的结果,因此编译器可能会完全跳过计算。顺便说一下:在分析时,应该使用-DNDEBUG编译所有的Eigen代码,以禁用Eigen中的断言。