丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號(hào)安全和更好的產(chǎn)品體驗(yàn),強(qiáng)烈建議使用更快更安全的瀏覽器
此為臨時(shí)鏈接,僅用于文章預(yù)覽,將在時(shí)失效
人工智能開(kāi)發(fā)者 正文
發(fā)私信給叨叨
發(fā)送

0

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

本文作者: 叨叨 2017-04-21 18:10
導(dǎo)語(yǔ):PerfXLab澎峰科技創(chuàng)始人分享

提起矩陣計(jì)算,學(xué)過(guò)《高等數(shù)學(xué)》的人可能都聽(tīng)過(guò),但若不是這個(gè)領(lǐng)域的研究者,恐怕也只停在“聽(tīng)過(guò)”的程度。在矩陣計(jì)算領(lǐng)域,開(kāi)源項(xiàng)目OpenBLAS影響巨大,除IBM、華為等巨頭公司在使用外,還吸引了全球的研究院校、開(kāi)發(fā)者們關(guān)注。

雷鋒網(wǎng) AI 研習(xí)社近日有幸邀請(qǐng)到了澎峰科技創(chuàng)始人、OpenBLAS項(xiàng)目創(chuàng)始人和主要維護(hù)者張先軼,他將為我們介紹OpenBLAS開(kāi)源項(xiàng)目以及矩陣乘法的優(yōu)化。

嘉賓介紹

張先軼,中國(guó)科學(xué)院博士,MIT博士后,OpenBLAS開(kāi)源項(xiàng)目創(chuàng)始人和主要維護(hù)者,PerfXLab澎峰科技創(chuàng)始人。曾獲2016年中國(guó)計(jì)算機(jī)學(xué)會(huì)科技進(jìn)步二等獎(jiǎng)。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

張先軼師從張?jiān)迫淌?,在中科院取得高性能?jì)算博士學(xué)位。讀博期間,基于GotoBLAS的原有基礎(chǔ),他創(chuàng)建了開(kāi)源矩陣計(jì)算庫(kù)OpenBLAS,領(lǐng)導(dǎo)團(tuán)隊(duì)不斷進(jìn)行修補(bǔ)和維護(hù),目前在矩陣計(jì)算的細(xì)分領(lǐng)域,成為影響力較大的開(kāi)源項(xiàng)目。

他在MIT萌生創(chuàng)業(yè)想法,歸國(guó)之后,針對(duì)“深度學(xué)習(xí)”,創(chuàng)辦PerfXLab澎峰科技,為計(jì)算機(jī)視覺(jué)、語(yǔ)音識(shí)別等公司提供一體化性能優(yōu)化方案。雷鋒網(wǎng)【新智造】頻道此前曾采訪并報(bào)道了PerfXLab澎峰科技。

課程內(nèi)容

OpenBLAS項(xiàng)目介紹

矩陣乘法優(yōu)化算法

一步步調(diào)優(yōu)實(shí)現(xiàn)

以下為公開(kāi)課完整視頻,共64分鐘:

以下為公開(kāi)課內(nèi)容的文字及 PPT 整理。

雷鋒網(wǎng)的朋友們大家好,我是張先軼,今天主要介紹一下我們的開(kāi)源矩陣計(jì)算庫(kù)OpenBLAS以及矩陣乘法的優(yōu)化。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

首先,什么是BLAS?

BLAS是 Basic Linear Algebra Subprograms (基本線性代數(shù)子程序)的首字母縮寫,主要用來(lái)做基礎(chǔ)的矩陣計(jì)算,或者是向量計(jì)算。它分為三級(jí):

  • BLAS 1級(jí),主要做向量與向量間的dot或乘加運(yùn)算,對(duì)應(yīng)元素的計(jì)算;

  • BLAS 2級(jí),主要做矩陣和向量,就類似PPT中藍(lán)色部分所示,矩陣A*向量x, 得到一個(gè)向量y。除此之外,可能還會(huì)有對(duì)稱的矩陣變形;

  • BLAS 3級(jí),主要是矩陣和矩陣的計(jì)算,最典型的是A矩陣*B矩陣,得到一個(gè)C矩陣。由矩陣的寬、高,得到一個(gè)m*n的C矩陣。

為什么BLAS是一個(gè)非常重要的庫(kù)或者接口,是因?yàn)樗呛芏嗫茖W(xué)計(jì)算的核心之一。每年做超級(jí)計(jì)算機(jī)的排行榜,都要做LINPACK測(cè)試,該測(cè)試很多部分就是做BLAS 3級(jí)矩陣和矩陣的計(jì)算。此外,還有很多科學(xué)和工程的模擬,在轉(zhuǎn)換后都變成了一種矩陣上的操作。如果你把矩陣優(yōu)化的特別好的話,對(duì)整個(gè)應(yīng)用的提升,都是非常有幫助的。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

BLAS與 Deep Learning 的關(guān)系,深度學(xué)習(xí)這幾年火了之后,比如大家非常了解的Alexnet,如果做具體的性能劃分,PPT上的這張圖來(lái)源于某篇論文,cut down之后看每個(gè)部分花了多少時(shí)間,發(fā)現(xiàn)它大部分的時(shí)間花費(fèi)在卷積層(Conv Layer),另外不少時(shí)間花在了全連接層(FC layer)。卷基層目前通用的實(shí)現(xiàn)是展成矩陣,變成矩陣與矩陣的乘法,就是BLAS 3級(jí)。而全連接層一般是變成一個(gè)矩陣和向量的乘法,也落成了BLAS操作。

也就是說(shuō),基于矩陣類學(xué)習(xí)的深度學(xué)習(xí),有90%或者更多的時(shí)間是通過(guò)BLAS來(lái)操作的。當(dāng)然,隨著新的算法出現(xiàn),卷積層對(duì)3*3的卷積核有專門的算法,或者用FFT類類算法也可以做,但是在通用上,展矩陣來(lái)做也非常廣泛。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

目前,BLAS只是一個(gè)定義了的實(shí)現(xiàn)接口,但是具體的實(shí)現(xiàn)其實(shí)有很多種。從商業(yè)的角度來(lái)講,存在很多商業(yè)版本,比如說(shuō) Intel、AMD、NVIDIA、IBM公司等,基本上為了搭配自己的硬件,對(duì)其做了更優(yōu)的優(yōu)化,出了商業(yè)版本。

針對(duì)開(kāi)源的而言,有如下幾種,之前比較知名的是GoToBLAS,和OpenBLAS有很深的淵源,但是在2010年終止開(kāi)發(fā)了,有時(shí)間在給大家分析其背后的原因,主力的開(kāi)發(fā)人員后藤,離開(kāi)了UT Austin的研究組,進(jìn)入了公司,就終止了開(kāi)發(fā)。ATLAS是美國(guó)一個(gè)學(xué)校做的,OpenBLAS是我們基于GotoBLAS做的,BLIS是后藤走了之后,基于GotoBLAS擴(kuò)展出來(lái)的一個(gè)項(xiàng)目,目前還處在相對(duì)早期的階段,成熟度還差一些。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

OpenBLAS歷史已經(jīng)有幾年了,從2011年初開(kāi)始進(jìn)入,最初的原因是GotoBLAS放棄了,我們重新fork了一個(gè)社區(qū)發(fā)行版,繼續(xù)開(kāi)發(fā)和維護(hù),它的維護(hù)不是一個(gè)簡(jiǎn)單修BUG的過(guò)程,如果想要獲得比較好的性能,需要不停跟著硬件走,比如說(shuō)新出一種新的硬件架構(gòu),或者適配更廣的硬件架構(gòu),都要進(jìn)行一定的優(yōu)化,來(lái)獲得比較好的加速效果。OpenBLAS算是目前全球最好的開(kāi)源矩陣計(jì)算庫(kù),在去年的時(shí)候得到了中國(guó)計(jì)算機(jī)學(xué)會(huì)科技進(jìn)步二等獎(jiǎng),同時(shí)也進(jìn)入了很多主流的Linux安裝包,比如說(shuō)Ubuntu里面就有我們的OpenBLAS Package,你能想到的Linux發(fā)行版幾乎都進(jìn)去了,但這不是我們主動(dòng)去做的。還有一個(gè)OpenHPC的套件,也是最近做高性能計(jì)算的一個(gè)源。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

目前OpenBLAS的進(jìn)展是,支持幾乎全部的主流CPU處理器,同時(shí)都能達(dá)到比較好的優(yōu)化性能。從操作系統(tǒng)來(lái)說(shuō),基本上常見(jiàn)主流的OS都支持。整體上,從適配的處理器范圍和支持的操作系統(tǒng),在開(kāi)源庫(kù)中算是最廣的實(shí)現(xiàn)。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

因此,OpenBLAS的用戶也是比較多的。比如有開(kāi)源項(xiàng)目Julia語(yǔ)言、GNU octave等;深度學(xué)習(xí)方面有大家熟悉的mxnet、Caffe都可以選OpenBLAS,作為CPU端的計(jì)算backend; IBM公司、ARM公司也都在他們的產(chǎn)品里邊使用了OpenBLAS,NVIDIA公司在做一些跟CPU的對(duì)比測(cè)試時(shí),把OpenBLAS列為了一個(gè)基準(zhǔn)。其他還有一些做編譯器的以色列創(chuàng)業(yè)公司,還有國(guó)內(nèi)的一些互聯(lián)網(wǎng)公司,比如搜狗。前段時(shí)間還和搜狗公司的人聊過(guò),我們的庫(kù)在線上已經(jīng)穩(wěn)定運(yùn)行一年多以上的時(shí)間,所以說(shuō)它的工程質(zhì)量上還是還是可以的。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

IBM前段時(shí)間,因?yàn)樯疃葘W(xué)習(xí)非?;?,做了一個(gè)Power AI的軟件框架,可以看到,最上面一層是一些開(kāi)源的框架,底層的計(jì)算中就有我們的OpenBLAS。當(dāng)然是為了搭載他的服務(wù)器。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

簡(jiǎn)要的看一下性能,BLAS庫(kù)的性能是越高越好。在Intel的 Sandy Bridge平臺(tái)上,相比MKL的性能,基本上是重合在一起的,達(dá)到了一個(gè)相當(dāng)?shù)男阅堋?/p>

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

這張圖展示了在龍芯上做的一個(gè)結(jié)果,測(cè)得比較全,整體的BLAS多線程的,性能全測(cè)試了,性能比較高的都是我們,提高了一倍到兩倍。這是因?yàn)槲覀冡槍?duì)龍芯3A做了優(yōu)化,所以取得了非常好的效果。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

剛才主要介紹了OpenBLAS的性能和效果,我們?cè)贕itHub上做了托管,歡迎對(duì)矩陣乘法或優(yōu)化感興趣的同學(xué)能加入進(jìn)來(lái),貢獻(xiàn)代碼,我們公司愿意拿出一筆錢來(lái)支持這個(gè)項(xiàng)目繼續(xù)往前走。接下來(lái)會(huì)開(kāi)始一些技術(shù)類的干貨,主要講一下大家對(duì)優(yōu)化比較感興趣的部分,我參考了矩陣乘法的這幾篇教程,UT Austin Flame組做的教程。我把他的內(nèi)容基本上是摳出來(lái)了,一步步帶著大家過(guò)一下,如果我們從最簡(jiǎn)單的矩陣乘法實(shí)現(xiàn),到一個(gè)高性能的矩陣乘法實(shí)現(xiàn),大概是幾步,怎么來(lái)的?或者是為什么優(yōu)化,每一步能獲得多少性能收益。這樣大家對(duì)于一些優(yōu)化的其他程序,希望能提供一些幫助。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

我們首先看一下基本實(shí)現(xiàn)。

我想只要學(xué)過(guò)《線性代數(shù)》之類的,這種矩陣乘法,是一個(gè)非常簡(jiǎn)單的問(wèn)題,如果轉(zhuǎn)換成C代碼來(lái)做的話,就是一個(gè)三重循環(huán),我在這張圖里列出了一個(gè)【i j k】的三重循環(huán),這里面矩陣乘法的代碼就已經(jīng)是,它實(shí)現(xiàn)的功能就是矩陣A*矩陣B,加到矩陣C里面,C是結(jié)果矩陣,這里面C的代碼,和在課本上看到的累加的公式是一樣的。找到i行,對(duì)應(yīng)這個(gè)位置的結(jié)果C,把i行的每個(gè)元素,都取出來(lái)乘以B列,對(duì)應(yīng)的乘,然后加起來(lái)就可以得到這個(gè)結(jié)果。但是這種實(shí)現(xiàn),如果你放到現(xiàn)在的處理器上跑性能的話,和優(yōu)化后的BLAS庫(kù)的實(shí)現(xiàn),性能會(huì)差很多倍,甚至?xí)?0倍。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

為什么呢,我們就做了一下最后的性能測(cè)試

這張圖也是截自教程里,代表了一個(gè)性能圖,越高越好。這里的測(cè)試平臺(tái)是Intel core i5 ,只是測(cè)了單線程,沒(méi)管多線程的事情。這種初始實(shí)現(xiàn)可能是1 GFlop/s。隨著規(guī)模變大,矩陣的性能在下降是為什么呢?因?yàn)樵趯?shí)現(xiàn)的過(guò)程中,沒(méi)有考慮到cache的原因,當(dāng)矩陣比較小的時(shí)候,速度還能快一些,當(dāng)矩陣大了的時(shí)候,一定會(huì)跌下去,所以圖里就有一個(gè)下滑的過(guò)程。

這個(gè)是非常原始、基礎(chǔ)的實(shí)現(xiàn)。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

再往上走一步,怎么樣才能再稍微優(yōu)化一下。我們需要把矩陣的乘法順序調(diào)一下,我們?cè)谶@里做了一個(gè)小的分塊,把p單獨(dú)提到了一個(gè)函數(shù)里,以點(diǎn)乘的形式寫出來(lái),每次做一個(gè)1*4的結(jié)果,單獨(dú)提出來(lái)變成一個(gè)函數(shù)。p的這一步,要把計(jì)算順序稍微換一下,把i放到里面,j放到外面,這塊背景為什么要換一下,實(shí)際上是因?yàn)槲覀兗僭O(shè)矩陣在存儲(chǔ)的時(shí)候是以列優(yōu)先存儲(chǔ)的,在列項(xiàng)的數(shù)值是連續(xù)存儲(chǔ),行之間是有間隔的,這對(duì)于仿存更有優(yōu)勢(shì)。變成這樣的實(shí)現(xiàn)之后,對(duì)整體的性能其實(shí)沒(méi)什么幫助,那為什么換成這種形式來(lái)寫呢,是為了之后的優(yōu)化,留下一定的空間。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

當(dāng)矩陣比較小,在cache里面的時(shí)候,性能基本是沒(méi)什么變化的,但是超過(guò)cache的時(shí)候,它的性能稍微好了一點(diǎn),從剛才非常低的值,也達(dá)到了接近1GFlop/s主要的原因是對(duì)A(0,p)做了一定的復(fù)用,它省了一些cache。另外一方面,它本身在做循環(huán)的利用來(lái)說(shuō),相當(dāng)于比這部分做了一定循環(huán)的展開(kāi),所以在效率上得到了一定的提升。

這塊的復(fù)用,只從內(nèi)存讀取一次,所以對(duì)超過(guò)cache的情況有了一定改善。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

在這個(gè)基礎(chǔ)上,我們就需要看一下有什么更好的方法來(lái)做優(yōu)化。我們的基準(zhǔn)就是,AddDot1*4的基準(zhǔn)上怎么做,我們想到第一點(diǎn)做的是,我們可不可以用寄存器變量來(lái)做,而不是操作內(nèi)存。我可以申請(qǐng)一堆C 00,01這樣的寄存器變量,在C語(yǔ)言中是register double,還有矩陣A的部分,也用寄存器變量。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

剩下的操作都是一些寄存器的變量,當(dāng)然B還是之前的方式,最后再寫回C里面。它完成的流程基本跟與之前的實(shí)習(xí)一樣,只是我們引入了寄存器變量,讓更多的數(shù)據(jù)保存到寄存器里,而不是放到cache緩存里,來(lái)減輕cache的壓力,這也能獲得一部分性能的提升。

可以看到,紅色的線是我們優(yōu)化后的性能,達(dá)到了2GFlop/s,藍(lán)色的線是之前的性能,這里做的優(yōu)化就是利用寄存器降低cache的消耗,取得了50%左右的性能提升。完成了這一步之后,我們還可以再怎么樣做優(yōu)化呢?

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

我們剛才在A、C的部分,已經(jīng)用寄存器做了替換,那么B仿存這部分,我們有沒(méi)有可能也做一些優(yōu)化。在之前實(shí)現(xiàn)的時(shí)候,B部分每次的坐標(biāo)計(jì)算都需要算出來(lái),B訪問(wèn)每個(gè)位置都要算一次,這樣就引入了額外的開(kāi)銷,其實(shí)是可以避免的。

我們使用指針的方式,一開(kāi)始先把對(duì)應(yīng)的指針位置指好,每次計(jì)算的時(shí)候只要指針連續(xù)移動(dòng)就好,而不是每次讀一個(gè)位置重新算一遍,這樣速度就會(huì)快一些。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

我們看一下,做完這個(gè)小優(yōu)化之后,降低了B index的消耗之后,從剛才的2G F…達(dá)到了4G的性能。這塊的改善對(duì)于小矩陣有效果,大矩陣全都超出了cache范圍,就不會(huì)有效果的。所以假設(shè)矩陣都在cache里面,這塊也獲得了不小的性能提升。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

當(dāng)你完成這一部分的時(shí)候,你可以想,我把A矩陣做了寄存器替換,B矩陣通過(guò)index改進(jìn),我們下一步還能怎么做?

其實(shí)就是一個(gè)比較常用的方式,做展開(kāi)。

在最里層循環(huán),是不是可以展開(kāi)成4次,在做這個(gè)的時(shí)候,我們可以降低整個(gè)循環(huán)這部分的開(kāi)銷,而且讓它流水的情況更好。OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

這部分也會(huì)對(duì)性能有一些改善。這張圖比較的當(dāng)初在中間階段的時(shí)候比起開(kāi)始階段,得到了多少提升。通過(guò)使用寄存器變量,使用了指針,在做了一定的底層循環(huán)展開(kāi)之后,達(dá)到了紅色線的性能,已經(jīng)比藍(lán)色線有了明顯的提升,但是這個(gè)還不算完,只是一個(gè)基礎(chǔ)。但是在1*4的層面,已經(jīng)沒(méi)什么油水可挖了,所以我們需要在更上層找一些方法。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

在1*4的時(shí)候,A的值產(chǎn)生了一些重用,但是如果塊再放大一點(diǎn),比如說(shuō)變成4*4時(shí),也就是說(shuō)每次計(jì)算的時(shí)候算的是一個(gè)方塊,而不是列。這個(gè)對(duì)于整個(gè)的優(yōu)化來(lái)說(shuō),可以復(fù)用你的訪存,而且能夠更充分的發(fā)揮計(jì)算能力。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

當(dāng)我們變成小的這種4*4的方塊時(shí),AddDot函數(shù)也要寫成這個(gè)模式。當(dāng)然,這部分也要用剛才做過(guò)的那些1*4的方法,A這邊之前是1個(gè)值,現(xiàn)在是4個(gè)值,用寄存器的變量,C部分已經(jīng)是4*4共有16個(gè),也全都是寄存器變量,B的部分全部用指針來(lái)優(yōu)化。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

但這樣做的話,對(duì)于整體的性能提升是比較有限的。因?yàn)檫@只是一個(gè)初始的結(jié)果,可以看到,對(duì)于小矩陣,在cache范圍內(nèi),沒(méi)有什么起色。但是超過(guò)cache后,對(duì)于大規(guī)模的矩陣,是有了一定性能提升。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

在以4*4的結(jié)果優(yōu)化基礎(chǔ)上,我們可以再做進(jìn)一步的優(yōu)化和開(kāi)發(fā)。為什么要轉(zhuǎn)換成4*4的優(yōu)化,是因?yàn)槲覀儸F(xiàn)在CPU的處理器,基本上想獲得高的性能,必須要用向量化指令,不管是老的SSE2,AVX或者AVX 2.0等,對(duì)于CPU的優(yōu)化,如果想達(dá)到高性能,必須要用到單指令多數(shù)據(jù)的向量化指令。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

做了4*4的分塊之后,在這種情況下,會(huì)更有利于向量指令。在這里以向量指令重寫了這部分循環(huán)的內(nèi)容,當(dāng)然這部分指令我沒(méi)有任何的內(nèi)嵌匯編或者純匯編的操作,我就直接用了Intel Intrinsic的形式來(lái)寫,可以看到這部分寫的就是一個(gè)128位的sse,這是做一個(gè)雙精度浮點(diǎn)double的一個(gè)矩陣,數(shù)據(jù)都是double的,從A里把這兩個(gè)值load進(jìn)來(lái)。后兩個(gè)load進(jìn)這個(gè)向量寄存器里,B部分每次都要用load復(fù)制的這種指令load進(jìn)去,剩下的這塊基本都是用向量的Intrinsic的變量來(lái)做了操作,在這塊跟之前看起來(lái)差不多,所以在編譯的時(shí)候都變成了向量化的指令。這兩行就算前部分C的值,這部分就算后部分C的值。

通過(guò)這種向量寄存器的指令使用后,他的性能提升非常明顯,從剛才4G可以達(dá)到超過(guò)6G ,而且這一部分是一個(gè)整體的變化,cache內(nèi)向量加速效果是非常明顯的,基本上是翻了一倍。

下一步需要解決的是這個(gè)cache的問(wèn)題,問(wèn)題是沒(méi)有做大的分塊,超過(guò)cache大小之后性能就會(huì)下滑,要解決這個(gè)問(wèn)題的話,需要在更上一層做Blocking。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

轉(zhuǎn)換成代碼的話,在這一層做一個(gè)K的切分,下面一層做一個(gè)m的切分,至于kc和mc都是參數(shù)。這些參數(shù)都是可調(diào)的,都要根據(jù)L2 cache的大小進(jìn)行調(diào)整,然后每次做的是一個(gè)小塊c的矩陣乘,相當(dāng)于一個(gè)子問(wèn)題,這個(gè)子問(wèn)題的實(shí)現(xiàn)基本和剛才4*4的實(shí)現(xiàn)是一樣的。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

這一部分blocking做完的性能如圖所示,藍(lán)色的線是沒(méi)有做Blocking的性能,紅色線是做過(guò)之后。當(dāng)問(wèn)題規(guī)模在cache內(nèi),它的性能改善基本比較小,但是當(dāng)大規(guī)模的矩陣,通過(guò)做了這次Blocking之后,可以看到獲得了非常明顯的提升,變快了2倍。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

對(duì)于大矩陣,為了充分的利用cache,讓子問(wèn)題變小,提升它的數(shù)據(jù)局部性,在做其他問(wèn)題優(yōu)化的時(shí)候也很有必要的。下一步當(dāng)我們做到blocking的時(shí)候,如果只是代碼級(jí)別變化的時(shí)候,基本已經(jīng)做完了。

此后再進(jìn)一步優(yōu)化的點(diǎn),引入引入一些操作。當(dāng)我們分析程序存在的性能瓶頸,對(duì)于A的訪存和B的訪存是比較慢,很多訪存在矩陣中是不連續(xù)的,所以訪存性能就差了很多,一方面不能利用cache,一方面在TLB上也有影響,當(dāng)然C部分也有一些影響,C矩陣往往很大,沒(méi)有辦法做packing,只能對(duì)A和B來(lái)做,packing的意思是說(shuō),我在這里有一部分連續(xù)的內(nèi)存空間,m*k,對(duì)應(yīng)前面的mc和kc,在這塊內(nèi)存空間,在每次做計(jì)算之前,我把所需要用到的A的矩陣,從原始矩陣讀取出來(lái),存放到連續(xù)的一塊內(nèi)存空間里。 Packed Matrix A這個(gè)函數(shù)的具體實(shí)現(xiàn)非常簡(jiǎn)單,基本上就是從對(duì)應(yīng)的位置取出來(lái),放在連續(xù)的內(nèi)存地址就結(jié)束。

為什么會(huì)做這步操作呢?這步操作的意義在于,通過(guò)pack之后,下一步AddDot4*4里讀的元素就不是從A矩陣讀,而是從pack后緩存區(qū)的位置讀。一個(gè)好處是,A矩陣已經(jīng)預(yù)熱,放進(jìn)CPU的cache里了;第二個(gè)好處是,你可以看到我在存儲(chǔ)的時(shí)候,這種連續(xù)性的存儲(chǔ),讀的時(shí)候也是連續(xù)性讀取,效率會(huì)非常高,cache效率也非常高。加上通過(guò)pack這一步,對(duì)于性能的改善,是非常明顯的。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

這張圖是上一步的操作,做了packing之后,除了極小矩陣規(guī)模沒(méi)什么效果,或者引入了額外開(kāi)銷,效果還變差之外,絕大部分的性能提升是非常明顯的,有50%以上,達(dá)到了9GFlop/s。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

對(duì)于矩陣乘法實(shí)現(xiàn)的話,packing矩陣是一個(gè)非常重要的優(yōu)化方式。再往后大家會(huì)想,對(duì)于A來(lái)說(shuō)做了Packing,對(duì)于B是不是也能做Packing,同樣道理也是可以的,就是把它拷貝到一個(gè)連續(xù)空間。B部分的Packing操作和A部分類似,也是把它的數(shù)據(jù)從原始矩陣?yán)镒x出來(lái),然后放到一個(gè)連續(xù)空間里,使它的內(nèi)存訪問(wèn)做連續(xù)的訪存。當(dāng)然這部分,因?yàn)锽訪存是個(gè)流式的訪存,所以在這部分的改進(jìn)會(huì)稍微小一點(diǎn),相比A只有大概10%左右的提升。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

對(duì)于矩陣乘法實(shí)現(xiàn)的話,packing矩陣是一個(gè)非常重要的優(yōu)化方式。再往后大家會(huì)想,對(duì)于A來(lái)說(shuō)做了Packing,對(duì)于B是不是也能做Packing,同樣道理也是可以的,就是把它拷貝到一個(gè)連續(xù)空間。B部分的Packing操作和A部分類似,也是把它的數(shù)據(jù)從原始矩陣?yán)镒x出來(lái),然后放到一個(gè)連續(xù)空間里,使它的內(nèi)存訪問(wèn)做連續(xù)的訪存。當(dāng)然這部分,因?yàn)锽訪存是個(gè)流式的訪存,所以在這部分的改進(jìn)會(huì)稍微小一點(diǎn),相比A只有大概10%左右的提升。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

當(dāng)你完成到這一步的時(shí)候,相比最開(kāi)始三重循環(huán)的性能改進(jìn),你的矩陣乘法的性能已經(jīng)有很明顯的提升了。你如果想做的更好的話,內(nèi)部的核心可能不止要寫intrinsic的指令,還要寫內(nèi)嵌匯編,重排流水線,使硬件資源能夠發(fā)揮更多,可能還會(huì)提升10%。當(dāng)然這部分對(duì)實(shí)現(xiàn)BLAS比較重要,會(huì)摳的比較細(xì)。

我們?cè)僬w回顧一下矩陣乘法的算法,我把算法的這部分放到最后,從開(kāi)始一步步實(shí)現(xiàn)之后,做到最后大家可能看的比較清楚一些。A矩陣*B矩陣得到C矩陣,對(duì)應(yīng)的是最外層的循環(huán),每一步往下的時(shí)候,其實(shí)都是在做分塊,做分塊的原因剛才有提到,就是為了配合硬件結(jié)構(gòu),因?yàn)閙emory、cache等都是分層的,它是越來(lái)越小的,做分塊實(shí)際上是提高了cache的各層的利用率。

今天就分享到這里,謝謝大家。

問(wèn)答解答

問(wèn)題1:什么是訪存優(yōu)化?

張先軼:訪存優(yōu)化解決的是處理器讀取數(shù)據(jù)的性能。從計(jì)算上來(lái)說(shuō),是相對(duì)好優(yōu)化的,但是優(yōu)化訪存會(huì)非常困難,稠密矩陣乘法的數(shù)據(jù)還是相對(duì)規(guī)整的,讀數(shù)據(jù)的順序是有規(guī)則的,更容易優(yōu)化一些。但是我們也做過(guò)很多稀疏矩陣的優(yōu)化,比如稀疏矩陣乘向量的優(yōu)化,這個(gè)對(duì)訪存來(lái)說(shuō)更困難一些,因?yàn)闆](méi)有辦法預(yù)測(cè)到下一次訪存在什么位置,這造成了優(yōu)化的困難。

問(wèn)題2:OpenBLAS和其他矩陣庫(kù)有什么關(guān)系?

張先軼:OpenBLAS和其他BLAS實(shí)現(xiàn)其實(shí)都是完成了接口,BLAS只是接口的定義,具體來(lái)說(shuō)可以有多種實(shí)現(xiàn)。我們認(rèn)為我們OpenBLAS在開(kāi)源的實(shí)現(xiàn)是非常好的。如果是標(biāo)準(zhǔn)BLAS,有參考實(shí)現(xiàn),只是一個(gè)非常簡(jiǎn)單的Fortran實(shí)現(xiàn),性能很差的,我們要比他們快很多。MKL是Intel公司自己做的BLAS,我們跟他們相當(dāng)。Engien我們沒(méi)有完全測(cè)過(guò),它號(hào)稱自己做的很好,但是他們的做法在X86的平臺(tái)可能有些效果,但是對(duì)其他平臺(tái)的效果我表示懷疑。不過(guò)我沒(méi)有具體做對(duì)比測(cè)試,所以發(fā)言權(quán)不大。

問(wèn)題3:從入門到精通需要多久?

張先軼:如果我指導(dǎo)的話,幾個(gè)月時(shí)間就可以上手做一些事情。歡迎大家。

問(wèn)題4:比起高通的庫(kù)表現(xiàn)如何?

張先軼:說(shuō)實(shí)話高通的庫(kù)沒(méi)有測(cè)過(guò),我覺(jué)得它號(hào)稱比較快,是因?yàn)樵?2位的ARM上,我們OpenBLAS沒(méi)有做向量化優(yōu)化,高通的那個(gè)部分做了,所以它可能會(huì)比我們快一些,但是在我們公司內(nèi)部的PerfBLAS是優(yōu)化了的。

問(wèn)題5:分塊的目的是什么?

張先軼:就是優(yōu)化訪存,通過(guò)分塊之后讓訪存都集中在一定區(qū)域,能夠提高了數(shù)據(jù)局部性,從而提高cache利用率,性能就會(huì)更好。

問(wèn)題6:硬件不給力能玩神經(jīng)網(wǎng)絡(luò)么?

張先軼:我們給出的一個(gè)數(shù)據(jù)是,我們?cè)贏RM CortexA57的平臺(tái)上,4核1.7GHz,跑AlexNet模型,一張圖是150ms,這個(gè)速度還算比較快。另一方面我們還在做一些其他的模型,做了精簡(jiǎn)優(yōu)化,再配合底層庫(kù)的優(yōu)化。在某個(gè)小模型下,在跑一張小圖片的inference只用了50ms。所以,在ARM的處理器上,還是可以做到實(shí)時(shí)本地化的神經(jīng)網(wǎng)絡(luò)inference。

問(wèn)題7:內(nèi)部版本和開(kāi)源版本差別大么?

張先軼:內(nèi)部版本是針對(duì)深度學(xué)習(xí)做了一些差異化處理,性能高的可能會(huì)到1倍多,這部分的優(yōu)化,一部分是矩陣的規(guī)模,和剛才講的做方陣不一樣,深度學(xué)習(xí)的矩陣大部分是中小型,某個(gè)維度會(huì)比較小,要用到的優(yōu)化策略,或者分塊策略會(huì)不一樣,甚至有時(shí)候特別小根本不用分塊或packing,直接做可能更好一些。


雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見(jiàn)轉(zhuǎn)載須知。

OpenBLAS項(xiàng)目與矩陣乘法優(yōu)化 | AI 研習(xí)社

分享:
相關(guān)文章

編輯

雷鋒網(wǎng)北京編輯。關(guān)注人工智能,略雜。微信(yougo5654)可以找到我。
當(dāng)月熱門文章
最新文章
請(qǐng)?zhí)顚懮暾?qǐng)人資料
姓名
電話
郵箱
微信號(hào)
作品鏈接
個(gè)人簡(jiǎn)介
為了您的賬戶安全,請(qǐng)驗(yàn)證郵箱
您的郵箱還未驗(yàn)證,完成可獲20積分喲!
請(qǐng)驗(yàn)證您的郵箱
立即驗(yàn)證
完善賬號(hào)信息
您的賬號(hào)已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說(shuō)