c ++ 犰狳中的矩阵乘法非常慢
Matrix multiplication in c++ armadillo is very slow
我正在使用犰狳做一些基本的乘法运算,但由于某些原因需要很长时间才能完成。我对 c++ 很陌生,所以我可能做错了什么,但即使在这个非常基本的例子中我也看不到它:
#include <armadillo>
#include <iostream>
using namespace arma;
int main(){
arma::vec coefficients = {1.0, 1.09, 1.08};
arma::mat X = arma::mat(100000, 3, fill::randu) * coefficients;
cout << X.n_cols;
}
当我的意思是非常慢时,我已经 运行 这个例子几分钟了,但它没有完成
编辑
我 运行 使用 perf stat ./main
的脚本,但在一段时间后停止了它,因为它不应该花那么长时间。这是输出。
^C./main: Interrupt
Performance counter stats for './main':
257,169.20 msec task-clock # 1.003 CPUs utilized
3,342 context-switches # 12.995 /sec
215 cpu-migrations # 0.836 /sec
1,312 page-faults # 5.102 /sec
963,025,520,077 cycles # 3.745 GHz
542,959,361,927 instructions # 0.56 insn per cycle
113,002,342,332 branches # 439.409 M/sec
1,095,168,312 branch-misses # 0.97% of all branches
256.349026907 seconds time elapsed
147.860947000 seconds user
109.317743000 seconds sys
Armadillo 是一个 template-based 库,可以用作 header-only 库。只需包含它的 header 并确保你 link 有一些 BLAS 和 LAPACK 实现。像这样使用时,armadillo 假定您有可用的 BLAS 和 LAPACK 实现。如果您尝试在犰狳中使用任何需要它们的功能而不 link 与它们一起使用,您将得到 link 错误。如果你没有 BLAS and/or LAPACK,你可以更改 armadillo_bits/config.hpp
文件并注释掉那里的一些定义 这样犰狳使用它自己的(较慢的)实现该功能。
或者,armadillo 可以编译为包装器库,在这种情况下,您只需 link 使用“armadillo”包装器库。它的 CMake 代码将尝试在配置期间确定您可用的内容和“comment-out 适当的定义”,以防您没有可用的需求,这反过来将使其使用较慢的实现。 “配置”代码错误地确定您没有可用的 BLAS,因为 BLAS 是提供快速矩阵乘法的代码。
我的建议是确保您安装了 BLAS 和 LAPACK 并将犰狳用作 header-only 库,确保 link 您的程序带有 BLAS 和 LAPACK。
另一种选择是使用 conan 包管理器来安装犰狳。柯南最近添加了安装犰狳的配方。它的优点是它将安装犰狳所需的一切(它安装 openblas,它同时提供 BLAS 和 LAPACK 实现)并且它是系统不可知的(类似于 Python 中的虚拟环境)。
备注
在您提到的评论中,它与 g++ main.cpp -o main -DARMA_DONT_USE_WRAPPER -larmadillo -llapack
一起使用。原因是即使你安装了包装器库,如果你定义 ARMA_DONT_USE_WRAPPER
你实际上是在使用犰狳作为 header-only 库。您可以将 -larmadillo -llapack
替换为 -lblas -llapack
.
我正在使用犰狳做一些基本的乘法运算,但由于某些原因需要很长时间才能完成。我对 c++ 很陌生,所以我可能做错了什么,但即使在这个非常基本的例子中我也看不到它:
#include <armadillo>
#include <iostream>
using namespace arma;
int main(){
arma::vec coefficients = {1.0, 1.09, 1.08};
arma::mat X = arma::mat(100000, 3, fill::randu) * coefficients;
cout << X.n_cols;
}
当我的意思是非常慢时,我已经 运行 这个例子几分钟了,但它没有完成
编辑
我 运行 使用 perf stat ./main
的脚本,但在一段时间后停止了它,因为它不应该花那么长时间。这是输出。
^C./main: Interrupt
Performance counter stats for './main':
257,169.20 msec task-clock # 1.003 CPUs utilized
3,342 context-switches # 12.995 /sec
215 cpu-migrations # 0.836 /sec
1,312 page-faults # 5.102 /sec
963,025,520,077 cycles # 3.745 GHz
542,959,361,927 instructions # 0.56 insn per cycle
113,002,342,332 branches # 439.409 M/sec
1,095,168,312 branch-misses # 0.97% of all branches
256.349026907 seconds time elapsed
147.860947000 seconds user
109.317743000 seconds sys
Armadillo 是一个 template-based 库,可以用作 header-only 库。只需包含它的 header 并确保你 link 有一些 BLAS 和 LAPACK 实现。像这样使用时,armadillo 假定您有可用的 BLAS 和 LAPACK 实现。如果您尝试在犰狳中使用任何需要它们的功能而不 link 与它们一起使用,您将得到 link 错误。如果你没有 BLAS and/or LAPACK,你可以更改 armadillo_bits/config.hpp
文件并注释掉那里的一些定义 这样犰狳使用它自己的(较慢的)实现该功能。
或者,armadillo 可以编译为包装器库,在这种情况下,您只需 link 使用“armadillo”包装器库。它的 CMake 代码将尝试在配置期间确定您可用的内容和“comment-out 适当的定义”,以防您没有可用的需求,这反过来将使其使用较慢的实现。 “配置”代码错误地确定您没有可用的 BLAS,因为 BLAS 是提供快速矩阵乘法的代码。
我的建议是确保您安装了 BLAS 和 LAPACK 并将犰狳用作 header-only 库,确保 link 您的程序带有 BLAS 和 LAPACK。
另一种选择是使用 conan 包管理器来安装犰狳。柯南最近添加了安装犰狳的配方。它的优点是它将安装犰狳所需的一切(它安装 openblas,它同时提供 BLAS 和 LAPACK 实现)并且它是系统不可知的(类似于 Python 中的虚拟环境)。
备注
在您提到的评论中,它与 g++ main.cpp -o main -DARMA_DONT_USE_WRAPPER -larmadillo -llapack
一起使用。原因是即使你安装了包装器库,如果你定义 ARMA_DONT_USE_WRAPPER
你实际上是在使用犰狳作为 header-only 库。您可以将 -larmadillo -llapack
替换为 -lblas -llapack
.