犰狳 vs Eigen3 时序差异
Armadillo vs Eigen3 Timing Difference
我希望这个讨论可以帮助其他遇到 Armadillo 和 Eigen3 问题的人。
我写了一个包装器 class,Mat,它包装了犰狳库中的 arma::Mat 或 Eigen3 库中的 Eigen::Matrix。这是在编译时用标志控制的。
另外,我写了一个 Tensor class,它使用 Mat 作为存储。这个 class 的主要特征是使用 Voigt 符号来压缩高阶张量以正确存储在矩阵中。
最后,我编写了一个测试,将二阶张量(即矩阵)和一阶张量(即向量)相乘多次并记录完成运算符所需的时间。我用我的 Mat class 和我的 Tensor class.
来做这个
因为 Tensor 包装了 Mat,我预计它的时间会更长。犰狳就是这种情况,平均接近 20%。但是,在使用 Eigen 时,使用 Tensor 更快,这对我来说完全没有意义。
有什么特别之处吗?
编辑:提供更多详细信息。
我首先将 arma::Mat 包装成 myOwn::armaMat,将 Eigen::Matrix 包装成 myOwn::eigenMat。这两者都只是将 armadillo 和 Eigen 的 API 包装到一个通用框架中。最后,基于编译器标志,myOwn::Mat 包装了一个 armaMat 或一个 eigenMat。我不确定我们是否启用了任何优化标志。
如上所述,myOwn::Tensor使用myOwn::Mat作为存储。由于我将使用张量 class 的物理应用程序,它被模板化为 2D(即,如果它是二阶,则为 2×2)或 3D(即,3×3)。 (相比之下,Mat 可以是任意大小)。
我用于计时目的的运算符是:2×2 矩阵(二阶张量)乘以 2×1 矩阵(一阶张量)。仅使用 Mat 时,我实际上是在使用犰狳或 Eigen 的表达式模板。
当使用我的 Tensor class 时,我重载了 operator* 这样的:
template< typename T1, bool Sym >
moris::Mat< T1 >
operator*(
moris::Tensor< T1, 2, 2, true > const & aTensor1,
moris::Tensor< T1, 1, 2, Sym > const & aTensor2 )
{
moris::Mat< T1 > tVector(2, 1);
tVector(0) = aTensor1[0]*aTensor2[0] + aTensor1[2]*aTensor2[1];
tVector(1) = aTensor1[2]*aTensor2[0] + aTensor1[1]*aTensor2[1];
return tVector;
}
Tensor 上的 [] 运算符从底层存储 Mat 访问数据(通过 Voigt 约定)。
"It's complicated."
我们通过 add-on 包 RcppArmadillo and RcppEigen 为 Armadillo 和 Eigen 提供绑定到 R,所以比较和 horse-race 问题经常出现。
而且我认为没有明确的答案。更重要的是 "worse",Armadillo 通常指的是您安装的任何 LAPACK/BLAS,因此您可以使用多核并行性,而 Eigen 倾向于更喜欢它自己的例程。在准备我的 Rcpp book 时,我做了一些计时并找到了一些 counter-intuitive 结果。
在一天结束时,您可能只需要分析您的问题。
我希望这个讨论可以帮助其他遇到 Armadillo 和 Eigen3 问题的人。
我写了一个包装器 class,Mat,它包装了犰狳库中的 arma::Mat 或 Eigen3 库中的 Eigen::Matrix。这是在编译时用标志控制的。
另外,我写了一个 Tensor class,它使用 Mat 作为存储。这个 class 的主要特征是使用 Voigt 符号来压缩高阶张量以正确存储在矩阵中。
最后,我编写了一个测试,将二阶张量(即矩阵)和一阶张量(即向量)相乘多次并记录完成运算符所需的时间。我用我的 Mat class 和我的 Tensor class.
来做这个因为 Tensor 包装了 Mat,我预计它的时间会更长。犰狳就是这种情况,平均接近 20%。但是,在使用 Eigen 时,使用 Tensor 更快,这对我来说完全没有意义。
有什么特别之处吗?
编辑:提供更多详细信息。
我首先将 arma::Mat 包装成 myOwn::armaMat,将 Eigen::Matrix 包装成 myOwn::eigenMat。这两者都只是将 armadillo 和 Eigen 的 API 包装到一个通用框架中。最后,基于编译器标志,myOwn::Mat 包装了一个 armaMat 或一个 eigenMat。我不确定我们是否启用了任何优化标志。
如上所述,myOwn::Tensor使用myOwn::Mat作为存储。由于我将使用张量 class 的物理应用程序,它被模板化为 2D(即,如果它是二阶,则为 2×2)或 3D(即,3×3)。 (相比之下,Mat 可以是任意大小)。
我用于计时目的的运算符是:2×2 矩阵(二阶张量)乘以 2×1 矩阵(一阶张量)。仅使用 Mat 时,我实际上是在使用犰狳或 Eigen 的表达式模板。
当使用我的 Tensor class 时,我重载了 operator* 这样的:
template< typename T1, bool Sym >
moris::Mat< T1 >
operator*(
moris::Tensor< T1, 2, 2, true > const & aTensor1,
moris::Tensor< T1, 1, 2, Sym > const & aTensor2 )
{
moris::Mat< T1 > tVector(2, 1);
tVector(0) = aTensor1[0]*aTensor2[0] + aTensor1[2]*aTensor2[1];
tVector(1) = aTensor1[2]*aTensor2[0] + aTensor1[1]*aTensor2[1];
return tVector;
}
Tensor 上的 [] 运算符从底层存储 Mat 访问数据(通过 Voigt 约定)。
"It's complicated."
我们通过 add-on 包 RcppArmadillo and RcppEigen 为 Armadillo 和 Eigen 提供绑定到 R,所以比较和 horse-race 问题经常出现。
而且我认为没有明确的答案。更重要的是 "worse",Armadillo 通常指的是您安装的任何 LAPACK/BLAS,因此您可以使用多核并行性,而 Eigen 倾向于更喜欢它自己的例程。在准备我的 Rcpp book 时,我做了一些计时并找到了一些 counter-intuitive 结果。
在一天结束时,您可能只需要分析您的问题。