比较OpenBLAS,Intel MKL和Eigen的矩阵相乘性能


对于机器学习的很多问题来说,计算的瓶颈往往在于大规模以及频繁的矩阵运算,主要在于以下两方面:

  • (Dense/Sparse) Matrix – Vector product
  • (Dense/Sparse) Matrix – Dense Matrix product

如何使机器学习算法运行更高效摆在我们面前,很多人都会在代码中直接采用一个比较成熟的矩阵运算数学库,面对繁多的数学库,选择一个合适的库往往会令人头疼,这既跟你的运算环境有关,也跟你的运算需求有关,不是每个库都能完胜的。

这篇文章的主要目的就是比较几个常见的BLAS库的矩阵运算性能,分别是

  1. EIGEN: 是一个线性算术的C++模板库。功能强大、快速、优雅以及支持多平台,可以使用该库来方便处理一些矩阵的操作,达到类似matlab那样的快捷。 需要定义 EIGEN_NO_DEBUG 阻止运行时assertion。编译单线程版本需要开启
    -DEIGEN_DONT_PARALLELIZE. 在试验中,我们采用 EIGEN 原生 BLAS 实现。
  2. Intel MKL: 英特尔数学核心函数库是一套经过高度优化和广泛线程化的数学例程,专为需要极致性能的科学、工程及金融等领域的应用而设计。它可以为当前及下一代英特尔处理器提供性能优化,包括更出色地与 Microsoft Visual Studio、Eclipse和XCode相集成。英特尔
    MKL 支持完全集成英特尔兼容性 OpenMP 运行时库,以实现更出色的 Windows/Linux 跨平台兼容性。在试验中的多线程版本需要链接到 mkl_gnu_thread,而不是 mkl_intel_thread,单线程版本需要链接到 mkl_sequential_thread。
  3. OpenBLAS: 是一个高性能多核 BLAS 库,是 GotoBLAS2 1.13 BSD 版本的衍生版。OpenBLAS 的编译依赖系统环境,并且没有原生单线程版本,在实验这哦那个,通过设置 OMP_NUM_THREADS=1 来模拟单线程版本,可能会带来一点点的性能下降。

每个测试程序的编译都采用 “-O4 -msse2 -msse3 -msse4” 优化, 通过设置 OMP_NUM_THREADS 来控制使用的线程数量. 除了 OpenBLAS,其他两个库的测试程序都分别有单线程和多线程的编译版本。

如果MKL编译出现问题,建议参考Intel
Math Kernel Library Link Line Advisor

  • 单线程版本

我在实验中进行了一系列的非稀疏矩阵相乘运算,矩阵规模也逐渐增大,单线程的运行时间如下表所示,其中采用的测试轮数为5轮,其中红色表示性能最好的一组实验结果。

Matrix-Dimension Eigen MKL OpenBLAS
500 0.04159 0.03122 0.03058
1000 0.31789 0.24339 0.23730
1500 1.04589 0.81445 0.79869
2000 2.37567 1.92036 1.87102
2500 4.68266 3.78569 3.64548
3000 8.28073 6.42630 6.29797
3500 13.07470 10.25096 9.98417
4000 19.34550 15.21931 14.87500
4500 27.52767 21.45024 21.18227
5000 37.67552  29.31631 29.07229

从图中可以看出,OpenBLAS的性能最好,MKL的表现也很不错,而EIGEN的表现却很糟糕。

  • 多线程版本

在多线程的测试中,我们采用多个CPU核心来做矩阵乘法运算,所有的结果也同样采用5轮训练,我们采用的CPU核数分别是8,16,32,48。

  • Cores = 8
Matrix-Dimension Eigen MKL OpenBLAS
1000 0.05658 0.03955 0.06468
2000 0.34981 0.26200 0.23879
3000 1.20781 0.85449 0.80737
4000 2.65490 1.90273 1.88366
5000 5.03304 3.73005 3.67966
6000 8.78654 6.52766 6.31980
7000 13.55611 10.13758 10.07120
8000 19.81634 15.03530 14.89440
9000 29.11329 21.54359 21.26992
10000 39.01563 29.93075 29.22034

  • Cores = 16
Matrix-Dimension Eigen MKL OpenBLAS
1000 0.05708 0.02185 0.03897
2000 0.26694 0.13807 0.30461
3000 0.70686 0.43692 0.93511
4000 1.45129 0.97720 2.06761
5000 2.59477 1.90665 2.49280
6000 5.43438 3.30945 7.01299
7000 8.01124 5.17896 6.84496
8000 11.22280 7.81439 12.99240
9000 15.15625 11.08906 21.82488
10000 19.91151 15.22039 30.86908

  • Cores = 32
Matrix-Dimension Eigen MKL OpenBLAS
1000 0.04003 0.02792 0.02244
2000 0.51213 0.14363 0.16990
3000 1.13647 0.51105 0.54635
4000 1.58793 1.10219 1.26401
5000 2.88341 2.07923 2.48735
6000 5.92779 3.42785 4.26794
7000 7.91650 5.32176 6.69391
8000 11.96467 7.65395 9.98951
9000 17.45420 10.28328 14.14108
10000 23.31314 15.10077 19.34171

  • Cores = 40
Matrix-Dimension Eigen MKL OpenBLAS
1000 0.03691 0.02877 0.01779
2000 0.37739 0.14037 0.13655
3000 0.61183 0.41057 0.44113
4000 2.43670 1.02625 1.01414
5000 3.18099 1.91092 1.97898
6000 8.24002 2.96157 3.40685
7000 11.59889 4.68312 5.38634
8000 9.50613 6.98434 7.95971
9000 14.83066 9.60891 11.37585
10000 23.67187 15.52151 15.52680

  • Cores = 48
Matrix-Dimension Eigen MKL OpenBLAS
1000 0.03635 0.02398 0.01548
2000 0.36417 0.13408 0.11496
3000 2.32388 0.39291 0.36669
4000 2.32030 1.13244 0.85790
5000 2.08269 1.75812 1.66785
6000 8.70766 2.98694 2.85609
7000 8.23543 4.62340 4.53257
8000 21.18603 6.68886 6.72820
9000 19.86504 9.59635 9.50597
10000 16.10920 13.13038 13.04432

可以看出,MKL和OpenBLAS都提供了比较好的性能,MKL性能还更好一点,在各别多线程条件下了,可能某些原因或者我机器设置的问题,出现了各别性能异常,比如小矩阵运算时间反倒比大矩阵运算长,或者更多的线程却不能提供更好的性能。这些情况后面可能还需要查一查。

  • 伸缩性

另外,我也测试了使用不同的cpu核数对性能的影响,下面两个图描述了把cpu从1增加到20的条件下,5000×5000的矩阵相乘的时间开销和加速比。

  • 结论

就我的测试环境而言,Intel MKL 和 OpenBLAS 似乎是矩阵相乘运算方面性能最佳的 BLAS 库,在多核以及不同规模的矩阵方面都具有较好的伸展性和稳定性,而对于单线程情况,OpenBLAS相比 MKL 在性能上有一定提升。

本文参考gcdart的文章,代码可以下载。

【神经网络与深度学习】【C/C++】比较OpenBLAS,Intel MKL和Eigen的矩阵相乘性能的更多相关文章

  1. 【神经网络与深度学习】【Qt开发】【VS开发】从caffe-windows-visual studio2013到Qt5.7使用caffemodel进行分类的移植过程

    [神经网络与深度学习][CUDA开发][VS开发]Caffe+VS2013+CUDA7.5+cuDNN配置成功后的第一次训练过程记录<二> 标签:[神经网络与深度学习] [CUDA开发] ...

  2. (转)神经网络和深度学习简史(第一部分):从感知机到BP算法

    深度|神经网络和深度学习简史(第一部分):从感知机到BP算法 2016-01-23 机器之心 来自Andrey Kurenkov 作者:Andrey Kurenkov 机器之心编译出品 参与:chen ...

  3. [DeeplearningAI笔记]神经网络与深度学习人工智能行业大师访谈

    觉得有用的话,欢迎一起讨论相互学习~Follow Me 吴恩达采访Geoffrey Hinton NG:前几十年,你就已经发明了这么多神经网络和深度学习相关的概念,我其实很好奇,在这么多你发明的东西中 ...

  4. 【吴恩达课后测验】Course 1 - 神经网络和深度学习 - 第二周测验【中英】

    [中英][吴恩达课后测验]Course 1 - 神经网络和深度学习 - 第二周测验 第2周测验 - 神经网络基础 神经元节点计算什么? [ ]神经元节点先计算激活函数,再计算线性函数(z = Wx + ...

  5. 【吴恩达课后测验】Course 1 - 神经网络和深度学习 - 第一周测验【中英】

    [吴恩达课后测验]Course 1 - 神经网络和深度学习 - 第一周测验[中英] 第一周测验 - 深度学习简介 和“AI是新电力”相类似的说法是什么? [  ]AI为我们的家庭和办公室的个人设备供电 ...

  6. 对比《动手学深度学习》 PDF代码+《神经网络与深度学习 》PDF

    随着AlphaGo与李世石大战的落幕,人工智能成为话题焦点.AlphaGo背后的工作原理"深度学习"也跳入大众的视野.什么是深度学习,什么是神经网络,为何一段程序在精密的围棋大赛中 ...

  7. 如何理解归一化(Normalization)对于神经网络(深度学习)的帮助?

    如何理解归一化(Normalization)对于神经网络(深度学习)的帮助? 作者:知乎用户链接:https://www.zhihu.com/question/326034346/answer/730 ...

  8. 【神经网络与深度学习】卷积神经网络(CNN)

    [神经网络与深度学习]卷积神经网络(CNN) 标签:[神经网络与深度学习] 实际上前面已经发布过一次,但是这次重新复习了一下,决定再发博一次. 说明:以后的总结,还应该以我的认识进行总结,这样比较符合 ...

  9. 【神经网络与深度学习】【CUDA开发】caffe-windows win32下的编译尝试

    [神经网络与深度学习][CUDA开发]caffe-windows win32下的编译尝试 标签:[神经网络与深度学习] [CUDA开发] 主要是在开发Qt的应用程序时,需要的是有一个使用的库文件也只是 ...

随机推荐

  1. cnblogs设置各级标题样式和目录

    向博客园申请js权限 我们需要进入博客园自定义博客模板的页面,向博客园管理团队申请页面运行js的权限. [博客园]->[设置]->[博客设置],点击页面上的js权限申请,然后填写申请的理由 ...

  2. Springboot项目报错【java.base/jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to java.base/java.net.URLClassLoader】

    1.发生问题: 升级了JDK9,发现原先的springboot项目起不来了,以为是maven中jdk配置有问题. 于是在pom中添加了 <plugin> <groupId>or ...

  3. What is a Digital Signature? 理解数字签名与数字证书

    What is a Digital Signature?An introduction to Digital Signatures, by David Youd Bob (Bob's public k ...

  4. vue cli3 + cube-ui 配置rem踩坑记录

    在install cube-ui时,选择了后编译,选中使用rem的时候会发现,怎么刷新页面的html字体被设置成了37.5px 感觉太大了,于是去寻找修改的办法,第一反应是webpack的配置,于是去 ...

  5. React组件(组件属性this.state和this.props,css样式修饰组件)

    目录: 1.创建组件的第一种方式 function2.将组件抽离为单独的jsx文件3.省略.jsx后缀, 配置webpack设置根目录4.创建组件的第二种方式--使用class关键字创建组件5.组件私 ...

  6. 通过远程 HTTP GET 请求载入信息

    jQuery.get(url, [data], [callback], [type]) 概述 通过远程 HTTP GET 请求载入信息. 这是一个简单的 GET 请求功能以取代复杂 $.ajax .请 ...

  7. redis 关闭持久化 实验验证

    前言 由于redis持久化(RDB),导致我们的线上的磁盘被写炸 线上服务器是 64H 512G 大概写了rdb文件是 200G左右,写满了当时的目录 处理策略 关闭持久化,由于之前的现象表示,我们线 ...

  8. 2019牛客暑期多校训练营(第二场)D bitset

    题意 给一个n个结点的带点权的图,找到第k小的团的权值 分析 用bitset表示团的状态,一个结点必须和团里的每个结点都连边才能加进去,所以可以直接用\(\&\)运算来判断一个结点是否能加进去 ...

  9. BeautifulSoup4 提取数据爬虫用法详解

    Beautiful Soup 是一个HTML/XML 的解析器,主要用于解析和提取 HTML/XML 数据. 它基于 HTML DOM 的,会载入整个文档,解析整个 DOM树,因此时间和内存开销都会大 ...

  10. HighCharts 动态设置 series

    var series = new Array(); var map = response.extend.map; $.each(map, function (key,values) { series. ...