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.