比較OpenBLAS,Intel MKL和Eigen的矩陣相乘性能


https://www.cnblogs.com/huty/p/8517892.html

   對於機器學習的很多問題來說,計算的瓶頸往往在於大規模以及頻繁的矩陣運算,主要在於以下兩方面:

  • (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的文章,代碼可以下載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM