CUDA學習之淺談cuBLAS
阿新 • • 發佈:2019-01-08
各位小夥伴們~!今天我們來談談CUDA中使用範圍很廣的一個程式設計庫——cuBLAS。
cuBLAS利用GPU加速向量、矩陣的線性運算。由於本人主要的研究方向是資料探勘,在資料探勘各種演算法中,包含著很多的向量、矩陣運算額,而隨著資料量的增大,普通的序列程式很難滿足速度的要求,而又不能一味的使用Matlab(因為這樣到企業中會被鄙視。。),多執行緒的程式又很難寫,因此,使用CUDA自帶的開發包cuBLAS和下一小節我們要談的針對稀疏矩陣的cuSPARSE包,就成了一種很自然的應對方式。
有的小夥伴又會有疑問了:資料量很大?記憶體能存下嗎?你的視訊記憶體能夠存下那麼大的矩陣或者向量嗎? 這個問題的答案是:我們暫且認為記憶體可以存的下,但視訊記憶體是存不下的(如果記憶體存不下,那麼就需要一種硬碟到記憶體的排程演算法,保證視訊記憶體需要的資料是在記憶體的,因此又滿足的上述的條件)。CUDA 6的開發包中,提供了一個新的API——CUBLASXT,它是在cuBLAS API的上層封裝了一個矩陣分塊演算法,解決了上述視訊記憶體不足的問題,但現有的CUBLASXT所提供的計算介面功能還比較有限,後面我們將會提到。
一、cuBLAS API
我們進入正題,從正題上來看cuBLAS API,可以分為資料描述結構體、功能函式、level-1函式、level-2函式、level-3函式和類BLAS擴充套件函式。資料描述結構體包含了矩陣和向量結構的描述,比如儲存矩陣的儲存格式等;功能函式包括建立流、拷貝向量和矩陣到GPU等功能操作;從level-1到類BLAS擴充套件函式分別定義了向量-向量運算、向量矩陣運算、矩陣矩陣運算和補充的運算。通過檢視cuBLAS文件,可以看到每個操作的輸入和輸出。整體上看,每個操作都有四種形式,分別對應四種資料型別。
使用cuBLAS API有兩個需要注意和小心的地方:
1. cuBLAS繼承了Fortran語言矩陣儲存的特性——矩陣按列儲存!這是個很重要的特性,還記得當年第一次使用cuBLAS API的時候,手動輸入了兩個小矩陣做矩陣乘法,得到的結果就是和手動計算的結果不同但又很相似,仔細觀察過後,發現輸入矩陣式按行儲存的,矩陣轉置後再相乘,就是cuBLAS計算出來的結果,瞬間恍然大悟!
2. 對於矩陣操作來說,引數中有lda或者ldb,這是個什麼東西,與m、n、k有什麼區別呢?不知道小夥伴們對GPU對齊儲存有沒有印象~對齊儲存能能夠保證執行緒的對齊訪問,降低訪問次數。如果對齊儲存了,會導致什麼後果呢?就是實際儲存的空間要比矩陣的維度大,因此lda,ldb就是描述實際儲存空間的維度,這個值是可以從申請空間的函式中得到的;m、n、k就是矩陣所表現出的維度大小,正如文件中的引數描述部分寫到的類似lda>=max(1, m)的要求。
實際使用cuBLAS還是很簡單的,按照API將引數對應好,就可以了,而且速度是很快的。
PS:如果想要的操作在前3個level的API中沒有找到,及得到類BLAS API中查檢視~。
二、CUBLASXT API
接下來談談CUDA6.0提出的CUBLASXT API。這個API解決了矩陣運算中由於矩陣過大,不能全部同時儲存在GPU視訊記憶體的問題。該API會自動的將矩陣分塊,並根據使用者設定的CPU-GPU運算百分比,在CPU-GPU平臺下進行矩陣運算,這裡的GPU可以是多於1個GPU。API同cuBLAS API很類似,只不過是多了使用者設定塊大小、CPU-GPU運算百分比、裝置引數的過程。這麼方便的演算法有什麼弊端嗎?答案是:有。
首先,現在能夠支援CUBLASXT API的GPU裝置還是比較少的,一塊主機板上至少要有一個Tesla K10或者GeForce GTX690的GPU才可以,另外,只有64位版本的CUDA才能支援該API。
另外,矩陣運算的複雜度並沒有降低,只是簡單的將矩陣分塊運算。不知道小夥伴們有沒有了解過矩陣分塊運算的strassen演算法,該演算法通過矩陣分塊的方式將矩陣乘法O(n3)的複雜度降低到O(n2.81),畢竟資料量大的話,降低複雜度才是王道,而不是簡單的將矩陣分塊。
相信Nvida公司能夠將CUDA的cuBLAS包更加的完善,能夠支援更多的裝置,能夠更方便的供使用者使用,CUBLASXT就是一個很好的例子,已經給了大家很多的驚喜!
非常感謝能夠從頭到尾看完的小夥伴們的支援,留下你看完該帖子的感受吧,可以是支援的,也可以是反對的,也可以是技術的交流~因為有你們的支援,CSDN CUDA版塊才能越辦越好~!
cuBLAS利用GPU加速向量、矩陣的線性運算。由於本人主要的研究方向是資料探勘,在資料探勘各種演算法中,包含著很多的向量、矩陣運算額,而隨著資料量的增大,普通的序列程式很難滿足速度的要求,而又不能一味的使用Matlab(因為這樣到企業中會被鄙視。。),多執行緒的程式又很難寫,因此,使用CUDA自帶的開發包cuBLAS和下一小節我們要談的針對稀疏矩陣的cuSPARSE包,就成了一種很自然的應對方式。
有的小夥伴又會有疑問了:資料量很大?記憶體能存下嗎?你的視訊記憶體能夠存下那麼大的矩陣或者向量嗎?
一、cuBLAS API
我們進入正題,從正題上來看cuBLAS API,可以分為資料描述結構體、功能函式、level-1函式、level-2函式、level-3函式和類BLAS擴充套件函式。資料描述結構體包含了矩陣和向量結構的描述,比如儲存矩陣的儲存格式等;功能函式包括建立流、拷貝向量和矩陣到GPU等功能操作;從level-1到類BLAS擴充套件函式分別定義了向量-向量運算、向量矩陣運算、矩陣矩陣運算和補充的運算。通過檢視cuBLAS文件,可以看到每個操作的輸入和輸出。整體上看,每個操作都有四種形式,分別對應四種資料型別。
使用cuBLAS API有兩個需要注意和小心的地方:
1. cuBLAS繼承了Fortran語言矩陣儲存的特性——矩陣按列儲存!這是個很重要的特性,還記得當年第一次使用cuBLAS API的時候,手動輸入了兩個小矩陣做矩陣乘法,得到的結果就是和手動計算的結果不同但又很相似,仔細觀察過後,發現輸入矩陣式按行儲存的,矩陣轉置後再相乘,就是cuBLAS計算出來的結果,瞬間恍然大悟!
2. 對於矩陣操作來說,引數中有lda或者ldb,這是個什麼東西,與m、n、k有什麼區別呢?不知道小夥伴們對GPU對齊儲存有沒有印象~對齊儲存能能夠保證執行緒的對齊訪問,降低訪問次數。如果對齊儲存了,會導致什麼後果呢?就是實際儲存的空間要比矩陣的維度大,因此lda,ldb就是描述實際儲存空間的維度,這個值是可以從申請空間的函式中得到的;m、n、k就是矩陣所表現出的維度大小,正如文件中的引數描述部分寫到的類似lda>=max(1, m)的要求。
實際使用cuBLAS還是很簡單的,按照API將引數對應好,就可以了,而且速度是很快的。
PS:如果想要的操作在前3個level的API中沒有找到,及得到類BLAS API中查檢視~。
二、CUBLASXT API
接下來談談CUDA6.0提出的CUBLASXT API。這個API解決了矩陣運算中由於矩陣過大,不能全部同時儲存在GPU視訊記憶體的問題。該API會自動的將矩陣分塊,並根據使用者設定的CPU-GPU運算百分比,在CPU-GPU平臺下進行矩陣運算,這裡的GPU可以是多於1個GPU。API同cuBLAS API很類似,只不過是多了使用者設定塊大小、CPU-GPU運算百分比、裝置引數的過程。這麼方便的演算法有什麼弊端嗎?答案是:有。
首先,現在能夠支援CUBLASXT API的GPU裝置還是比較少的,一塊主機板上至少要有一個Tesla K10或者GeForce GTX690的GPU才可以,另外,只有64位版本的CUDA才能支援該API。
另外,矩陣運算的複雜度並沒有降低,只是簡單的將矩陣分塊運算。不知道小夥伴們有沒有了解過矩陣分塊運算的strassen演算法,該演算法通過矩陣分塊的方式將矩陣乘法O(n3)的複雜度降低到O(n2.81),畢竟資料量大的話,降低複雜度才是王道,而不是簡單的將矩陣分塊。
相信Nvida公司能夠將CUDA的cuBLAS包更加的完善,能夠支援更多的裝置,能夠更方便的供使用者使用,CUBLASXT就是一個很好的例子,已經給了大家很多的驚喜!
非常感謝能夠從頭到尾看完的小夥伴們的支援,留下你看完該帖子的感受吧,可以是支援的,也可以是反對的,也可以是技術的交流~因為有你們的支援,CSDN CUDA版塊才能越辦越好~!