性能比拼!超詳細的Tengine GEMM矩陣乘法彙編教程

2021-02-13 我愛計算機視覺

點擊我愛計算機視覺標星,更快獲取CVML新技術

Tengine 是OPEN AI LAB 針對前端智能設備開發的軟體開發包,核心部分是一個輕量級,模塊化,高性能的AI 推斷引擎,並支持用DLA、GPU、xPU作為硬體加速計算資源異構加速。

本文為Open AI Lab 工作人員投稿,對深度學習的核心操作GEMM進行了詳細的使用介紹,歡迎對模型部署AI推斷感興趣的朋友關注Tengine。

https://github.com/OAID/Tengine

很多剛入門Tengine的開發者想研讀Tengine彙編代碼,卻苦於沒有好的彙編入門教程,沒有大神帶入門,自己看又看不懂,怎麼辦?福利來了,Tengine帶來了一份超詳細的gemm彙編教程。

什麼是GEMM? 它的英文全稱是 GEneral Matrix to Matrix Multiplication (通用矩陣的矩陣乘法),Gemm在神經網絡的計算中佔據很重要的位置。Why gemm is at the heart of deep learning[1]介紹了為什麼GEMM在深度學習計算中如此重要,以及卷積計算中是如何使用GEMM。linux作業系統: 本教程的編譯腳本使用的是Makefile

step1部分的代碼直接執行:

這個程序中我們計算的矩陣乘法是 A(m,k) * B(k,n) =C(m,n):

矩陣乘法的純C簡潔實現:

void gemm_pure_c(float* A, float* B, float* C,int m,int n,int k){   for(int i=0;i<m;i++)    {       for(int j=0;j<n;j++)       {           C[i*n+j]=0.f;           for(int p=0;p<k;p++)           {                C[i*n+j]+=A[i*k+p]*B[p*n+j];           }       }    }}

OpenBLAS[2]是一個開源的基礎線性代數計算庫,BLAS的英文全稱Basic Linear Algebra Subprograms,它在不同的處理器上都做了優化。在Linux上,可以直接通過apt-get安裝這個庫:
sudo apt-get install libopenblas-dev

運行一下step2的代碼

makeexport OMP_NUM_THREADS=1taskset 0x1 ./test

在RK3399上得到的結果是

[m n k]:        256 128 256[openblas]:     4.68 ms[pure c]:       32.22 ms[blas VS pure_C]:  maxerr=0.000076

可以看出,調用OpenBLAS庫的性能明顯優於純C實現。

Step3:調用Tengine 16x4 kernel的gemm

這部分教程以 Tengine[3]源碼中的 sgemm_4x16_interleave.S[4]為例子,對彙編代碼做了一些簡化,只支持k為4的倍數的情況。在使用Tengine的4x16 kernel之前, 首先要對矩陣A和矩陣B的數據進行interleave。什麼是interleave呢?Interleave叫交錯排布,表示對數據進行重新排布,為了計算的時候讀取數據時能更好地利用緩存。這裡我們對矩陣A的數據是對m中的每16個元素進行重排, 對矩陣B的數據是對n的每4個元素進行重排。

Tengine的4x16 kernel計算的n=4,m=16的情況,目前支持的k是4的倍數:加載A的數據到寄存器 v4,v5,v6,v7,v8,v9,v10,v11
    ldr q0,[x1]        ldr q1, [x1,0x10]      ldp q2, q3, [x1,0x20]     ldp q4, q5, [x2]    ldp q6, q7, [x2,0x20]          ldp q8, q9, [x2,0x40]    ldp q10,q11,[x2,0x60]

下面的動圖演示了4x16的kernel的每條指令是如何進行計算的

最後的彙編對應的是把輸出數據保存

    stp     q16, q17 ,[x0]    stp     q18, q19 ,[x0, #0x20]    stp     q20, q21 ,[x0, #0x40]    stp     q22, q23 ,[x0, #0x60]    stp     q24, q25 ,[x0, #0x80]    stp     q26, q27 ,[x0, #0xa0]    stp     q28, q29 ,[x0, #0xc0]    stp     q30, q31 ,[x0, #0xe0]

我們在RK3399上執行step3的代碼:

cd step3makeexport OMP_NUM_THREADS=1taskset 0x1 ./test

可以看出, Tengine的4x16 kernel性能在這三種實現中是最優的。

[m n k]:        256 256 256[tengine 4x16]: 7.71 ms[openblas]:     9.55 ms[pure c]:       316.00 ms[blas VS tengine]:  maxerr=0.000061

這個教程的代碼只是一個示例,part3的代碼只支持:你可以修改代碼來支持任意數值的k,可參考[sgemm_4x16_interleave.S][4]這個彙編代碼,添加 loop1.你可以把 interleave_B4 函數替換成彙編,以優化性能。你可以嘗試寫一個 4x4_kernel.S 的armv8彙編你可以嘗試寫一個 4x4_kernel.S 的armv7彙編

 

教程源碼連結或點擊閱讀原文獲取:

https://github.com/lyuchuny3/Tengine_gemm_tutorial

[1] Why gemm is at the heart of deep learning (https://petewarden.com/2015/04/20/why-gemm-is-at-the-heart-of-deep-learning/)[2]OpenBLAS (https://www.openblas.net/)[3]Tengine (https://github.com/OAID/Tengine )[4]sgemm_4x16_interleave.S(https://github.com/OAID/Tengine/blob/master/executor/operator/arm64/conv/sgemm_4x16_interleave.S )

模型壓縮與應用部署交流群

關注最新最前沿的神經網絡模型壓縮、減枝、AI推斷技術,掃碼添加CV君拉你入群,(如已為CV君其他帳號好友請直接私信)

(請務必註明:部署)

喜歡在QQ交流的童鞋,可以加52CV官方QQ群:805388940。

(不會時時在線,如果沒能及時通過驗證還請見諒)

長按關注我愛計算機視覺

相關焦點

  • AutoKernel實力展示:將GEMM的性能提升200倍!
    AutoKernel特色:· 低門檻: 無需底層優化彙編的知識門檻· 簡單易用: 提供docker環境,無需安裝環境,plugin一鍵集成到推理框架Tengine· 高效率: 無需手寫優化彙編,一鍵生成優化代碼,一鍵部署
  • 算子優化 | 將GEMM的性能提升200倍!AutoKernel算子優化工具正式開源(附源碼連結)
    實踐本部分將帶領大家一步步優化矩陣乘法GEMM。無需手工擼代碼,編寫繁雜冗長的底層彙編代碼,只需十幾行簡潔的調度代碼。2.1、優化的本質在詳細講解優化步驟前,我們先談談優化的本質。/build.sh 7  ==> 最極致優化下圖展示了在Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz的電腦上的優化效果,無需手工擼代碼,無需編寫繁雜冗長的底層彙編代碼,只需十幾行簡潔的調度代碼, 就能性能優化200+倍~
  • 通用矩陣乘(GEMM)優化與卷積計算
    (https://github.com/flame/how-to-optimize-gemm/wiki)介紹了如何採用各種優化方法,將最基礎的計算改進了約七倍(如圖二)。詳細的可以參考原文。因此我們可以再進一步,利用向量操作提高計算的性能。在介紹向量化計算的細節時,偽代碼是很難理解的,下面依據圖六介紹量化計算的具體過程。圖六左側部分的三幅小圖分別展示了兩個 4×4 矩陣相乘向量化的要素:首先是計算一個輸出元素使用到的輸入元素;然後是對各個矩陣內存的編碼,均以行優先的形式編號;最後是向量化的具體計算方法。
  • 張先軼博士:OpenBLAS項目與矩陣乘法優化
    接下來會開始一些技術類的乾貨,主要講一下大家對優化比較感興趣的部分,我參考了矩陣乘法的這幾篇教程,UT Austin Flame組做的教程。我把他的內容基本上是摳出來了,一步步帶著大家過一下,如果我們從最簡單的矩陣乘法實現,到一個高性能的矩陣乘法實現,大概是幾步,怎麼來的?或者是為什麼優化,每一步能獲得多少性能收益。這樣大家對於一些優化的其他程序,希望能提供一些幫助。
  • 矩陣乘法
    矩陣相乘最重要的方法是一般矩陣乘積。它只有在第一個矩陣的列數(column)和第二個矩陣的行數(row)相同時才有意義。
  • Im2Col+GEMM的改進方法MEC,一種更加高效的卷積計算策略
    因此,對卷積層的加速對整個網絡的性能非常關鍵。目前,對卷積層的計算一般有以下幾種方式:Im2Col+GEMM。Caffe/DarkNet/MxNet多種框架都使用了這種計算方法,因為將卷積操作轉化為矩陣運算之後就可以方便的使用很多矩陣加速庫如MKL,OpenBlas,Eigen等等。想詳細了解這個算法的讀者可以點一下上一節的連結。FFT加速。
  • Tengine-Ngnix高級版
    Tengine的性能和穩定性已經在大型的網站如淘寶網,天貓商城等得到了很好的檢驗。它的最終目標是打造一個高效、穩定、安全、易用的Web平臺。從2011年12月開始,Tengine成為一個開源項目,Tengine團隊在積極地開發和維護著它。Tengine團隊的核心成員來自於淘寶、搜狗等網際網路企業。
  • GEMM詳細分析
    如上圖為標準的矩陣乘法的維度表示簡單的寫一個偽代碼如下for
  • 基於MLIR實現GEMM編譯優化
    GEMM(General Matrix Multiplication)即通用矩陣乘法運算,由於其計算行為具有一定的複雜性以及規律性,是編譯算法研究的絕佳場景。MLIR是近期非常熱門的一個編譯器軟體框架,是工業界及科研界研究的一個熱點,其提供了一套靈活的軟體基礎設施,對中間表達式(IR)及其相互之間的轉換進行規範的管理,是一個非常友好的編譯器開發平臺[1][2]。
  • 矩陣乘法的純Python實現 | 離開Python庫!!
    在《這篇文章》中,我們有簡單提到「矩陣乘法」的相關知識,如果你不記得了,可以複習一下這張圖片。想起來了沒?本篇文章將深入探討在沒有機器學習庫的情況下如何從零實現矩陣乘法!你有沒有想過在沒有任何複雜的機器學習庫的情況下處理機器學習問題?
  • Python numpy 矩陣特殊加、乘法與循環優化
    python 矩陣的特殊加、乘法與循環優化經常進行python矩陣運算的可能會用到不同的矩陣操作,numpy官方文檔給出了不同操作的說明,一般需要的都可以在那裡找到
  • 最小二乘法詳細介紹
    高斯使用的最小二乘法的方法發表於1809年他的著作《天體運動論》中,而法國科學家勒讓德於1806年獨立發現「最小二乘法」,但因不為世人所知而默默無聞。1829年,高斯提供了最小二乘法的優化效果強於其他方法的證明,見高斯-馬爾可夫定理。2.舉個最簡單的例子理解最小二乘現在大家都越來越重視自己的身體健康。
  • 斐波那契數列與矩陣乘法的聯繫以及其python實現
    學習高等數學、線性代數等課程時,可能有數學老師提到過斐波那契數列的另類解法--利用矩陣求解。數列的遞推公式為:f(1)=1,f(2)=2,f(n)=f(n-1)+f(n-2)(n>=3)   用矩陣表示為:
  • 實測Tengine開源的Dubbo功能
    Tengine在開源以後大受歡迎,成為了Nginx最好的替代品之一,官方網站(http://tengine.taobao.org/)。Dubbo是阿里巴巴開源的一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和發現。
  • 面向晶片的推理框架Tengine-Lite
    PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig export PKG_CONFIG_PATHsource /etc/bash.bashrcsudo updatedb在完成後很多小夥伴可能出現使用pkg-config opencv --modversion時超不到
  • 矩陣相乘在GPU上的終極優化:深度解析Maxas彙編器工作原理
    在從事深度學習框架的實現工作時,了解到 Nervana 有一個稱為 Maxas 的彙編代碼生成器項目,可以生成性能超過 nVidia 官方版本的矩陣相乘的 GPU 機器碼,由此對其工作原理產生興趣。如上節所述,分片算法在利用了片上高速緩存之後,不但小片矩陣的乘法速度可以大大加快,還可以利用計算小片矩陣相乘的時間將下一個小片從主內存傳送至片上共享內存,換句話說此時整個矩陣相乘的時間已經完全由小片矩陣相乘所決定,如果要進一步提高性能就要在小片矩陣相乘上做文章了。在共享內存內部做矩陣相乘雖然已經很快了,但距離硬體性能的極限還是有距離,主要瓶頸是兩個。
  • Tengine lite Windows Clion 環境配置
    昨天剛在筆記本上編譯好tengine,這篇就先記錄一下tengine在windows上的編譯過程。,切換到tengine-lite分支git clone https://github.com/OAID/Tengine.git  tengine-lite然後使用"x86 Native Tools Command Prompt for VS 201x" 或者 "x64