【神经网络与深度学习】【C/C++】比较OpenBLAS,Intel MKL和Eigen的矩阵相乘性能
比较OpenBLAS,Intel MKL和Eigen的矩阵相乘性能
对于机器学习的很多问题来说,计算的瓶颈往往在于大规模以及频繁的矩阵运算,主要在于以下两方面:
- (Dense/Sparse) Matrix – Vector product
- (Dense/Sparse) Matrix – Dense Matrix product
如何使机器学习算法运行更高效摆在我们面前,很多人都会在代码中直接采用一个比较成熟的矩阵运算数学库,面对繁多的数学库,选择一个合适的库往往会令人头疼,这既跟你的运算环境有关,也跟你的运算需求有关,不是每个库都能完胜的。
这篇文章的主要目的就是比较几个常见的BLAS库的矩阵运算性能,分别是
- EIGEN: 是一个线性算术的C++模板库。功能强大、快速、优雅以及支持多平台,可以使用该库来方便处理一些矩阵的操作,达到类似matlab那样的快捷。 需要定义 EIGEN_NO_DEBUG 阻止运行时assertion。编译单线程版本需要开启
-DEIGEN_DONT_PARALLELIZE. 在试验中,我们采用 EIGEN 原生 BLAS 实现。 - Intel MKL: 英特尔数学核心函数库是一套经过高度优化和广泛线程化的数学例程,专为需要极致性能的科学、工程及金融等领域的应用而设计。它可以为当前及下一代英特尔处理器提供性能优化,包括更出色地与 Microsoft Visual Studio、Eclipse和XCode相集成。英特尔
MKL 支持完全集成英特尔兼容性 OpenMP 运行时库,以实现更出色的 Windows/Linux 跨平台兼容性。在试验中的多线程版本需要链接到 mkl_gnu_thread,而不是 mkl_intel_thread,单线程版本需要链接到 mkl_sequential_thread。 - 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的矩阵相乘性能的更多相关文章
- 【神经网络与深度学习】【Qt开发】【VS开发】从caffe-windows-visual studio2013到Qt5.7使用caffemodel进行分类的移植过程
[神经网络与深度学习][CUDA开发][VS开发]Caffe+VS2013+CUDA7.5+cuDNN配置成功后的第一次训练过程记录<二> 标签:[神经网络与深度学习] [CUDA开发] ...
- (转)神经网络和深度学习简史(第一部分):从感知机到BP算法
深度|神经网络和深度学习简史(第一部分):从感知机到BP算法 2016-01-23 机器之心 来自Andrey Kurenkov 作者:Andrey Kurenkov 机器之心编译出品 参与:chen ...
- [DeeplearningAI笔记]神经网络与深度学习人工智能行业大师访谈
觉得有用的话,欢迎一起讨论相互学习~Follow Me 吴恩达采访Geoffrey Hinton NG:前几十年,你就已经发明了这么多神经网络和深度学习相关的概念,我其实很好奇,在这么多你发明的东西中 ...
- 【吴恩达课后测验】Course 1 - 神经网络和深度学习 - 第二周测验【中英】
[中英][吴恩达课后测验]Course 1 - 神经网络和深度学习 - 第二周测验 第2周测验 - 神经网络基础 神经元节点计算什么? [ ]神经元节点先计算激活函数,再计算线性函数(z = Wx + ...
- 【吴恩达课后测验】Course 1 - 神经网络和深度学习 - 第一周测验【中英】
[吴恩达课后测验]Course 1 - 神经网络和深度学习 - 第一周测验[中英] 第一周测验 - 深度学习简介 和“AI是新电力”相类似的说法是什么? [ ]AI为我们的家庭和办公室的个人设备供电 ...
- 对比《动手学深度学习》 PDF代码+《神经网络与深度学习 》PDF
随着AlphaGo与李世石大战的落幕,人工智能成为话题焦点.AlphaGo背后的工作原理"深度学习"也跳入大众的视野.什么是深度学习,什么是神经网络,为何一段程序在精密的围棋大赛中 ...
- 如何理解归一化(Normalization)对于神经网络(深度学习)的帮助?
如何理解归一化(Normalization)对于神经网络(深度学习)的帮助? 作者:知乎用户链接:https://www.zhihu.com/question/326034346/answer/730 ...
- 【神经网络与深度学习】卷积神经网络(CNN)
[神经网络与深度学习]卷积神经网络(CNN) 标签:[神经网络与深度学习] 实际上前面已经发布过一次,但是这次重新复习了一下,决定再发博一次. 说明:以后的总结,还应该以我的认识进行总结,这样比较符合 ...
- 【神经网络与深度学习】【CUDA开发】caffe-windows win32下的编译尝试
[神经网络与深度学习][CUDA开发]caffe-windows win32下的编译尝试 标签:[神经网络与深度学习] [CUDA开发] 主要是在开发Qt的应用程序时,需要的是有一个使用的库文件也只是 ...
随机推荐
- .md(markdown)基础语法
markdown基础语法笔记,方便翻看. 1. 标题 标题有3中写法,可混写: (1)# ***,前面#,后面文字,注意,#与文字间有空格,1-6个#分别表示h1-h6,h1.h2下有横线 (2)== ...
- mybatis使用@Insert @SelectKey 执行插入语句时获得主键自增长值(转)
@Insert(" insert into table(c1,c2) " + " values (#{c1},#{c2}) ") @SelectKey(resu ...
- java内存区域以及GC回收
参考资料: http://www.cnblogs.com/zhguang/p/3257367.html 概要: Java GC机制主要完成3件事:确定哪些内存需要回收,确定什么时候需要执行GC,如何执 ...
- docker stack /swarm 替代 docker-compose 进行部署
之前一直用docker-compose开发了几个单例的service, 今天开始压力测试, 结果发现postgres的CPU负载很重, 就想设置cpus 结果发现docker-compose V3之后 ...
- codevs 2977 二叉堆练习1x
时间限制: 10 s 空间限制: 32000 KB 题目等级 : 白银 Silver 题目描述 Description 已知一个二叉树,判断它是否为二叉堆(小根堆) 输入描述 Input ...
- python celery 异步学习
1.运行redis 2.安装celery:pip install celery[redis] 3.vim task.py import time from celery import Celery b ...
- MySQL_8.0与5.7区别之账户与安全
一.创建用户和用户授权 MySQL5.7创建用户和用户授权命令可以同时执行 grant all privileges on *.* to 'Gary'@'%' identified by 'Gary@ ...
- JavaScript数字计算精度丢失的问题和解决方案
一.JS数字精度丢失的一些典型问题 1. 两个简单的浮点数相加:0.1 + 0.2 != 0.3 // true,下图是firebug的控制台截图: 看看java的计算结果:是不是让你很不能接受 再来 ...
- 分享如何在github上为代码创建一个链接
从自学前端到现在差不多一个月了,在此期间,一直有一种困惑,如何将自己电脑中编写的代码生成一个链接,以便可以发布呢?今天有幸被高人指点一二,现将其分享. 第一步,网上注册一个github账号 第二步,新 ...
- 6.HBase时髦谨慎财会会计
1.基本概念和原理 2.核心知识点 3.安装部署 4.Hbase开发