繁体   English   中英

本征矩阵乘法速度

[英]Eigen Matrix Multiplication Speed

我试图在C ++中进行线性代数数值计算。 我将Python Numpy用于快速模型,并且我想找到一个C ++线性代数包以进一步提高速度。 本征似乎是一个很好的起点。

我使用大型密集矩阵乘法编写了一个小型性能测试,以测试处理速度。 在Numpy中,我正在这样做:

import numpy as np
import time

a = np.random.uniform(size = (5000, 5000))
b = np.random.uniform(size = (5000, 5000))
start = time.time()
c = np.dot(a, b)
print (time.time() - start) * 1000, 'ms'

在C ++ Eigen中,我正在这样做:

#include <time.h>
#include "Eigen/Dense"

using namespace std;
using namespace Eigen;

int main() {
    MatrixXf a = MatrixXf::Random(5000, 5000);
    MatrixXf b = MatrixXf::Random(5000, 5000);
    time_t start = clock();
    MatrixXf c = a * b;
    cout << (double)(clock() - start) / CLOCKS_PER_SEC * 1000 << "ms" << endl;
    return 0;
}

我已经在文档中以及在编译优化标志上的stackoverflow上进行了一些搜索。 我试图使用以下命令来编译程序:

g++ -g test.cpp -o test -Ofast -msse2

使用-Ofast优化标志编译的C ++可执行文件的运行速度比简单的无优化编译速度快约30倍或以上。 我的2015 Macbook pro大约会在10000ms内返回结果。

同时,Numpy将在大约1800ms内返回结果。

与Numpy相比,我期望使用Eigen的性能有所提高。 但是,这没有达到我的预期。

我是否错过了可以进一步提高本征性能的编译标志? 还是有可以打开的多线程开关为我带来额外的性能提升? 我对此很好奇。

非常感谢你!

编辑于2016年4月17日:

根据@ggael的答案进行搜索后,我想出了这个问题的答案。

最好的解决方案是通过链接到英特尔MKL作为本征的后端进行编译。 对于osx系统,可以在这里找到库。 安装了MKL后,我尝试使用Intel MKL链接行顾问程序为Eigen启用MKL后端支持。

我以这种方式为所有MKL启用进行编译:

g++ -DEIGEN_USE_MKL_ALL -L${MKLROOT}/lib -lmkl_intel_lp64 -lmkl_core -lmkl_intel_thread -liomp5 -lpthread -lm -ldl -m64 -I${MKLROOT}/include -I. -Ofast -DNDEBUG test.cpp -o test

如果MKLROOT有任何环境变量错误,只需运行MKL软件包中提供的环境设置脚本,该脚本默认安装在我的设备上的/ opt / intel / mkl / bin中。

使用MKL作为Eigen后端,在我的2.5Ghz Macbook Pro上,两个5000x5000操作的矩阵乘法将在大约900ms内完成。 这比我设备上的Python Numpy快得多。

为了回答OSX方面的问题,首先请记住,在OSX上g ++实际上是clang ++的别名,并且当前Apple的clang版本不支持openmp。 尽管如此,使用Eigen3.3-beta-1和默认的clang ++,我得到了macbookpro 2.6Ghz:

$ clang++ -mfma -I ../eigen so_gemm_perf.cpp  -O3 -DNDEBUG  &&  ./a.out
2954.91ms

然后,要获得对多线程的支持,您需要使用gcc编译器的最新版本,例如使用homebrew或macport。 在这里使用来自macport的gcc 5,我得到:

$ g++-mp-5 -mfma -I ../eigen so_gemm_perf.cpp  -O3 -DNDEBUG -fopenmp -Wa,-q && ./a.out
804.939ms

并使用clang 3.9:

$ clang++-mp-3.9 -mfma -I ../eigen so_gemm_perf.cpp  -O3 -DNDEBUG -fopenmp  && ./a.out
806.16ms

请注意,osx上的gcc不知道如何正确汇编AVX / FMA指令,因此您需要告诉它使用带有-Wa,-q标志的本机汇编程序。

最后,在devel分支中,您还可以告诉Eigen使用任何BLAS作为后端,例如来自Apple Accelerate的BLAS,如下所示:

$ g++ -framework Accelerate -DEIGEN_USE_BLAS -O3 -DNDEBUG so_gemm_perf.cpp  -I ../eigen  && ./a.out
802.837ms

使用VC2013编译您的小程序:

  • / fp:精确-10.5秒
  • / fp:strict-10.4s
  • / fp:快速-10.3秒
  • / fp:快速/ arch:AVX2-6.6秒
  • / fp:快速/ arch:AVX2 / openmp-2.7秒

因此,使用AVX / AVX2并启用OpenMP将大有帮助。 您也可以尝试链接到MKL( http://eigen.tuxfamily.org/dox/TopicUsingIntelMKL.html )。

暂无
暂无

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

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