點擊我愛計算機視覺標星,更快獲取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作業系統: 本教程的編譯腳本使用的是Makefilestep1部分的代碼直接執行:
這個程序中我們計算的矩陣乘法是 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。
(不會時時在線,如果沒能及時通過驗證還請見諒)
長按關注我愛計算機視覺