繁体   English   中英

基准矩阵乘法性能:C ++(特征)比Python慢​​得多

[英]Benchmarking matrix multiplication performance: C++ (eigen) is much slower than Python

我试图估计Python性能与C ++相比有多好。

这是我的Python代码:

a=np.random.rand(1000,1000) #type is automaically float64
b=np.random.rand(1000,1000) 
c=np.empty((1000,1000),dtype='float64')

%timeit a.dot(b,out=c)

#15.5 ms ± 560 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

这是我在发布机制中使用Xcode编译的C ++代码:

#include <iostream>
#include <Dense>
#include <time.h>

using namespace Eigen;
using namespace std;

int main(int argc, const char * argv[]) {
    //RNG generator
    unsigned int seed = clock();
    srand(seed);

    int Msize=1000, Nloops=10;

    MatrixXd m1=MatrixXd::Random(Msize,Msize);
    MatrixXd m2=MatrixXd::Random(Msize,Msize);
    MatrixXd m3=MatrixXd::Random(Msize,Msize);

    cout << "Starting matrix multiplication test with " << Msize << 
    "matrices" << endl;
    clock_t start=clock();
    for (int i=0; i<Nloops; i++)
        m3=m1*m2;
    start = clock() - start;

    cout << "time elapsed for 1 multiplication: " << start / ((double) 
CLOCKS_PER_SEC * (double) Nloops) << " seconds" <<endl;
return 0;

}

结果是:

Starting matrix multiplication test with 1000matrices
time elapsed for 1 multiplication: 0.148856 seconds
Program ended with exit code: 0

这意味着C ++程序慢了10倍。

或者,我试图在MAC终端中编译cpp代码:

g++ -std=c++11 -I/usr/local/Cellar/eigen/3.3.5/include/eigen3/eigen main.cpp -o my_exec -O3

./my_exec

Starting matrix multiplication test with 1000matrices
time elapsed for 1 multiplication: 0.150432 seconds

我知道非常相似的问题 ,然而,看起来问题出现在矩阵定义中。 在我的例子中,我使用默认的本征函数来从均匀分布创建矩阵。

谢谢,米哈伊尔

编辑:我发现,虽然numpy使用多线程,但Eigen默认不使用多个线程(由Eigen::nbThreads()函数检查)。 正如所建议的那样,我使用了-march=native选项,它将计算时间减少了3倍。考虑到我的MAC上可用的8个线程,我可以相信多线程numpy运行速度提高了3倍。

经过漫长而痛苦的安装和编译后,我在Matlab,C ++和Python中执行了基准测试。

我的电脑:MAC OS High Sierra 10.13.6,Intel(R)Core(TM)i7-7920HQ CPU @ 3.10GHz(4核,8线程)。 我有Radeon Pro 560 4096 MB,因此这些测试中没有涉及GPU(我从未配置过openCL并且没有在np.show_config()看到它)。

软件:Matlab 2018a,Python 3.6,C ++编译器:Apple LLVM版本9.1.0(clang-902.0.39.2),g ++ - 8(Homebrew GCC 8.2.0)8.2.0

1)Matlab性能:时间=(14.3±0.7)ms,执行10次运行

a=rand(1000,1000);
b=rand(1000,1000);
c=rand(1000,1000);
tic
for i=1:100
    c=a*b;
end
toc/100

2)Python性能( %timeit a.dot(b,out=c) ):15.5 + - 0.8

我还为python安装了mkl库。 numpy链接到mkl:14.4 + -0.7 - 它有所帮助,但很少。

3)C ++性能。 对原始(请参阅问题)代码进行了以下更改:

  • noalias功能可以避免不必要的时间矩阵创建。

  • 用c ++ 11 chorno库测量时间

在这里,我使用了一堆不同的选项和两个不同的编译器:

3.1 clang++ -std=c++11 -I/usr/local/Cellar/eigen/3.3.5/include/eigen3/eigen main.cpp -O3

执行时间~146 ms

3.2 Added -march=native option:

执行时间~46 + -2 ms

3.3 Changed compiler to GNU g++ (in my mac it is called gpp by custom-defined alias):

gpp -std=c++11 -I/usr/local/Cellar/eigen/3.3.5/include/eigen3/eigen main.cpp -O3

执行时间222毫秒

3.4 Added - march=native option:

执行时间~45.5 + - 1 ms

此时我意识到Eigen不使用多个线程。 我安装了openmp并添加了-fopenmp标志。 请注意,在最新的clang版本上,openmp不起作用,因此从现在开始我不得不使用g ++。 我还确保通过监视Eigen::nbthreads()的值并使用MAC OS活动监视器来实际使用所有可用线程。

3.5  gpp -std=c++11 -I/usr/local/Cellar/eigen/3.3.5/include/eigen3/eigen main.cpp -O3 -march=native -fopenmp

执行时间:16.5±0.7毫秒

3.6最后,我安装了Intel mkl库。 在代码中使用它们非常简单:我刚刚添加了#define EIGEN_USE_MKL_ALL宏,就是这样。 虽然很难链接所有的库:

gpp -std=c++11 -DMKL_LP64 -m64 -I${MKLROOT}/include -I/usr/local/Cellar/eigen/3.3.5/include/eigen3/eigen -L${MKLROOT}/lib -Wl,-rpath,${MKLROOT}/lib -lmkl_intel_ilp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm -ldl   main.cpp -o my_exec_intel -O3 -fopenmp  -march=native

执行时间:14.33 + -0.26 ms。 (编者注:这个答案最初声称已经使用了-DMKL_ILP64 ,这是不受支持的 。也许以前是,或者恰好工作。)

结论:

  • Python / Matlab中的矩阵 - 矩阵乘法得到了高度优化。 不可能(或者,至少非常难)做得更好(在CPU上)。

  • CPP代码(至少在MAC平台上)只有在完全优化的情况下才能实现类似的性能,其中包括全套优化选项和Intel mkl库。 我可以用openmp支持安装旧的clang编译器,但由于单线程性能相似(~46 ms),看起来这样做无济于事。

  • 用原生英特尔编译器icc尝试它会很棒。 不幸的是,这是专有软件,与英特尔mkl库不同。

感谢您的有益讨论,

米哈伊尔

编辑:为了比较,我还使用cublasDgemm函数对我的GTX 980 GPU进行了基准测试。 计算时间= 12.6 ms,与其他结果兼容 CUDA几乎和CPU一样好的原因如下:我的GPU对双打的优化程度很低。 使用浮点数,GPU时间= 0.43毫秒,而Matlab是7.2毫秒

编辑2:为了获得显着的GPU加速,我需要对更大尺寸的矩阵进行基准测试,例如10k x 10k

编辑3:由于不支持 ILP64,因此将接口从MKL_ILP64更改为MKL_LP64

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM