OpenMP版本矩陣相乘

URNOTJANET發表於2017-12-27

說明:

1.轉載請聯絡本人

2.程式碼在最後

實驗目標

通過編寫OpenMp版本的矩陣乘法(SGEMM)熟悉OpenMP程式設計模型,鼓勵嘗試不同的優化策略。

問題描述

在數學領域中,矩陣乘法將兩個矩陣進行相乘,得出另一個矩陣。
矩陣乘法在實際應用中有廣泛的使用,並被不同的程式語言所實現。1979年制定的基礎線性代數子程式標準(BLAS)描述了基本的線性代數運算,包括矩陣乘法。
BLAS分為三個級別,而矩陣-矩陣運算屬於第三級。 下式中,a、b為常數,A、B、C為矩陣。

C = aAB + bC


實驗要求

  1. 根據記憶體大小測不同規模矩陣的處理速度(GFLOPS/s),並給出計算公式
  2. 請計算系統的理論峰值,如果沒有達到理論峰值,嘗試給出原因

解決思路與方法

1.實現OpenMP下的普通版本的矩陣相乘:

用OpenMP編寫兩個n階的方陣A和B的相乘程式,結果存放在方陣C中,其中乘法用for編譯製導語句實現並行化操作,並調節for編譯製導中schedule的引數,使得執行時間最短
使用num_threads()函式指定並行執行緒數

2.優化版:

1)利用矩陣分塊

將矩陣乘法的計算轉化為其各自分塊矩陣相乘而後相加,能夠有效減少乘數矩陣和被乘數矩陣調入記憶體的次數,可加快程式執行。

2)用一維陣列表示二維

二維陣列在記憶體中也是一維陣列,但是可以通過轉換的公式,減少實際的乘法次數,以達到優化效果

注:分塊和一維表示不能同時進行。
(同時進行會報錯,可能是涉及到分塊的問題,一維的位置規則和分塊的位置不太一樣)

實驗

1.實驗環境
本機: CPU:i5-4210U 記憶體:8G OS: Windows10 1607
實驗室:CPU: i7-7700K GPU:GTX 1080 記憶體:8G DDR4 OS:Ubuntu 16.04

2.結果及分析
不同規模矩陣處理速度公式:

Speed = 2*N^3/time Gflops

(對結果矩陣C分析知,每個迴圈進行一次加和乘操作)
GPU理想值:單精度浮點運算運算能力是9Tflops 一個TFLOPS(teraFLOPS)等於每秒一萬億(=10^12)次的浮點運算
時間/s 256 512 1024 2048
本地 0.37 3.72 50.81 /
GPU 0.049 0.47 3.68 104.3

GPU(時間/s) 256 512 1024 2048
分塊 0.046 0.46 3.75 29.9
一維陣列 0.019 0.364 2.91 82.1

注:每個時間是執行三次取平均值的結果(執行緒數量均為64)
P.S Max=2048下執行緒數量從64換到256,時間上沒有任何的進步……

結論

在GPU環境下,矩陣相乘的執行速度明顯提高,但在維度較大的情況下,對程式碼進行優化會有更好的效果。

程式碼地址

個人GitHub:Icarusintheworld

相關文章