文獻標識碼: A
DOI:10.16157/j.issn.0258-7998.191070
中文引用格式: 王春林,譚克俊. 基于脈動陣列的卷積計算模塊硬件設(shè)計[J].電子技術(shù)應(yīng)用,2020,46(1):57-61.
英文引用格式: Wang Chunlin,Tan Kejun. Hardware design of convolution calculation module based on systolic array[J]. Application of Electronic Technique,2020,46(1):57-61.
0 引言
在過去的幾年里,深度神經(jīng)網(wǎng)絡(luò)(Deep Neural Network,DNN)在圖像分類、目標檢測[1]及圖像分割等領(lǐng)域起到十分重要的作用。這些使用的各種DNNs及其拓撲結(jié)構(gòu)中,卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network,CNN)是其中最為常見的實現(xiàn)方式。目前在硬件加速方案中,主要有基于CPU、GPU以及FPGA三種主流方案??紤]到 CPU性能限制和GPU功耗高的問題,采用FPGA來實現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)成為了一種可行的實現(xiàn)方式,例如文獻[2]在FPGA中實現(xiàn)神經(jīng)網(wǎng)絡(luò)目標檢測系統(tǒng),其檢測速度與能效均優(yōu)于CPU。采用傳統(tǒng)的Verilog HDL或者VHDL硬件描述語言實現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)較為困難[3],高層次綜合(High Level Synthesis,HLS)將C/C++代碼通過特定的編譯器轉(zhuǎn)化為相應(yīng)的RTL級的代碼,降低了卷積神經(jīng)網(wǎng)絡(luò)的開發(fā)難度,減少了卷積神經(jīng)網(wǎng)絡(luò)的開發(fā)周期。
使用FPGA實現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)中卷積計算模塊的過程中,通常采用循環(huán)平鋪和循環(huán)展開[4]的方式實現(xiàn)。這種方式以擴大并行度來達到網(wǎng)絡(luò)的時間復(fù)雜度。但是當(dāng)輸入和輸出特征圖維度增加時,擴大并行度會帶來硬件設(shè)計中長廣播、多扇入/扇出的數(shù)據(jù)通路,導(dǎo)致卷積計算模塊無法在較高的主頻上運行。因此,很多神經(jīng)網(wǎng)絡(luò)加速器都使用脈動陣列來優(yōu)化加速器架構(gòu)設(shè)計,如谷歌TPU加速器[5]、ShiDianNao加速器[6]等。而在這些加速器架構(gòu)設(shè)計中大多是采用im2col[7]的方式,即將參與卷積計算的輸入特征圖和權(quán)重展開為兩個矩陣,然后進行矩陣乘法運算。這種實現(xiàn)方式因為卷積步長的存在而產(chǎn)生大量的數(shù)據(jù)重疊,不利于在FPGA的片上塊存儲器(Block RAM,BRAM)內(nèi)進行存儲。
為了解決上述存在的問題,本文提出一種基于脈動陣列的卷積計算模塊設(shè)計,將由并行展開所帶來的長數(shù)據(jù)通路變?yōu)槊總€處理單元的短數(shù)據(jù)通路;并按照存儲矩陣的坐標向卷積計算模塊中輸入特征圖數(shù)據(jù),以解決im2col方式存在的數(shù)據(jù)重疊,不利于BRAM存儲的問題。整體設(shè)計使用Vivado HLS開發(fā)環(huán)境進行實現(xiàn)與優(yōu)化。
1 本文工作
1.1 脈動陣列實現(xiàn)卷積計算模塊
脈動陣列(Systiloc Array)[8]是1970年KUNG H T[9]提出的一種應(yīng)用在片上多處理器的體系結(jié)構(gòu),由多個相同的、結(jié)構(gòu)簡單的計算單元(Processing Element,PE)以網(wǎng)格狀形式連接而成,具有并行性、規(guī)律性和局部通信的特征。信號處理算法如卡爾曼濾波[10]和數(shù)值線性代數(shù)算法都可以用脈動陣列來實現(xiàn)。本文卷積計算模塊中采用的脈動陣列實現(xiàn)方式如圖1所示。
在圖1中,I表示輸入特征圖,W表示權(quán)重參數(shù),O表示輸出特征圖,r、c分別表示特征圖的長和寬,m、n分別表示輸入特征圖與輸出特征圖的層數(shù)。在開始進行卷積運算之前,將特征圖數(shù)據(jù)輸入到BRAM中進行緩存,將權(quán)重輸入到每個PE中進行緩存。開始計算之后,輸入緩存中的數(shù)據(jù)沿脈動陣列的列方向進行傳輸,PE計算的結(jié)果沿脈動陣列行方向進行傳輸。非第0列的PE按照公式(1)進行計算:
式中PEin表示從輸入緩存或者上一個PE讀取輸入數(shù)據(jù),W表示PE緩存的權(quán)重數(shù)據(jù),PEout表示每個PE儲存的計算結(jié)果,cho與chi分別表示當(dāng)前PE的行列坐標。第0列的PE只進行乘法運算。在每一行PE的末尾處連接一個result緩存,用來累加和存儲每行最后一個PE輸出的結(jié)果,并在完成一個卷積核運算之后將存儲結(jié)果輸出到輸出緩存中。本文脈動陣列結(jié)構(gòu)設(shè)置為矩形脈動陣列,長和寬分別以輸入特征圖和輸出特征圖的層數(shù)來部署,并且每個PE在一個時鐘周期內(nèi)進行一個乘法和加法運算,根據(jù)這個條件可以得到所有PE完成計算所需要的時間計算公式:
式中,Tsum表示完成所有輸出特征圖的計算所需要的時間,R、C分別表示輸出特征圖的長和寬,Cin、Cout分別表示輸入特征圖層數(shù)和輸出特征圖層數(shù),K表示卷積核的邊長,Tprc表示每個時鐘周期所需要的時間。如果R和C的大小設(shè)置為5,Cin和Cout分別設(shè)置為3和8,K設(shè)置為3,Tprc為10 ns,根據(jù)公式(2)可以得到理論上需要的時間為2 340 ns。
1.2 卷積計算模塊硬件設(shè)計
根據(jù)1.1節(jié)中脈動陣列在卷積計算模塊中的實現(xiàn)方式,在Vivado HLS開發(fā)環(huán)境上對卷積計算模塊進行設(shè)計。卷積計算模塊分為三個部分:輸入階段、計算階段和累加輸出階段。
輸入階段的流程圖如圖2所示,圖中in(chi,ir,ic)表示BRAM存儲的輸入特征圖,ir、ic分別表示特征圖的長和寬。mid_in(cho,chi)和mid_out(cho,chi)分別表示每一個PE中的輸入和輸出緩存,CHI表示輸入特征圖的層數(shù),CHO表示輸出特征圖層數(shù),COUNT表示一個PE需要進行卷積運算的次數(shù)。chi、cho、loc表示三個變量,分別表示脈動陣列的列坐標、行坐標以及運行計數(shù)。根據(jù)圖2中的運行方式,每經(jīng)過一個時鐘周期,位于脈動陣列非0列的mid_in會從上一個相同行的mid_in中讀取輸入數(shù)據(jù)。位于脈動陣列的第0列的mid_in,會根據(jù)運行狀態(tài)判斷是否需要從BRAM中讀取輸入特征圖數(shù)據(jù)。
計算階段的流程圖如圖3所示,其中weight(cho,chi,kr,kc)表示緩存到PE中權(quán)重參數(shù),kr、kc分別表示卷積核的列坐標與行坐標。當(dāng)輸入階段結(jié)束之后,進入計算階段。位于脈動陣列非0排的mid_out會將mid_in中的數(shù)據(jù)與weight中的數(shù)據(jù)做乘法,再和上一個相同列的mid_out中的輸出數(shù)據(jù)做加法。位于脈動陣列第0排的mid_out則只做一次乘法。PE計算結(jié)果保存在當(dāng)前mid_out中。
累加輸出階段的流程圖如圖4所示,圖中out(cho,r,c)表示BRAM中輸出特征圖緩存,r、c分別表示輸出特征圖的列坐標與行坐標。result表示輸出緩存到BRAM之間的累加寄存器,用來將脈動陣列末尾行PE的結(jié)果進行累加,k表示寄存器運行的累加次數(shù)。當(dāng)一個卷積核運算完成之后,將結(jié)果按照當(dāng)前的行列坐標輸出到BRAM中的out緩存中,之后result寄存器清零,繼續(xù)下一次累加計算。
在這三個階段運行過程中,希望在每一個時鐘周期內(nèi),當(dāng)前PE可以從外部或者相鄰的PE中讀取一個數(shù)據(jù)進行乘加計算。因此使用#pragma HLS PIPELINE管道操作優(yōu)化指令,并設(shè)置流水為1級流水,保證每個時鐘內(nèi)都能夠開啟一次新的計算。在使用流水化操作之后,為了保證在輸入階段和計算階段的數(shù)據(jù)不會被覆蓋,采用移位寄存器的運行方式,由末尾的PE開始依次從相鄰的上一個PE讀取數(shù)據(jù),新數(shù)據(jù)最后再進行輸入。
同時,因為采用將權(quán)重固定到PE中的計算模式,所以將In和Out以數(shù)組的形式存放到BRAM中。因為每個BRAM最大可配置的輸入輸出端口數(shù)為2,所以當(dāng)同時從BRAM中輸入輸出數(shù)量大于2時,就需要等待上一個操作結(jié)束之后,再執(zhí)行下一個操作,這樣就無法達到1級流水所需要的時間間隔。因此使用#pragma HLS ARRAY_PARTITION variable=<variable> complete dim=X指令,其中<variable>表示需要展開的數(shù)組名,X表示需要展開的數(shù)組維度,將in(chi,ir,ic)和out(cho,r,c)按照第一個維度展開成多個數(shù)組,來匹配脈動陣列的輸入與輸出。
2 實驗結(jié)果與分析
本文在Vivado HLS 18.3開發(fā)環(huán)境上進行綜合與仿真,使用的FPGA芯片型號為賽靈思公司的xc7z020clg484-1,運行時鐘為100 MHz。使用輸入特征圖7×7大小的3層矩陣,得到的輸出特征圖為5×5的8層矩陣。卷積核采用8×3組大小為3×3的矩陣。單個PE的功能仿真波形如圖5所示。
其中,din0和din1分別表示輸入特征圖和權(quán)重數(shù)據(jù),din2表示從上一個相鄰PE中讀取的計算結(jié)果。dout表示乘加計算之后的結(jié)果,d0表示result寄存器中的輸入數(shù)據(jù),q0表示result寄存器的輸出數(shù)據(jù)。由于本文采用的時鐘頻率為100 MHz,每個時鐘周期為10 ns。從圖5中可以看出,當(dāng)ce0信號置1時,表示開始進行運算。之后在每一個時鐘周期內(nèi),都進行一次乘加運算,并將結(jié)果通過dout進行輸出。因為采用1級流水優(yōu)化指令,dout輸出的結(jié)果將會在下一個時鐘周期輸出到d0。然后進行累加操作。當(dāng)完成3×3次加法運算,輸出標志位we0信號置1,然后result寄存器將當(dāng)前的d0結(jié)果按照address0的地址通過q0輸出到指定BRAM上的輸出緩存中。然后d0清零,等待下一次計算開始。
卷積計算模塊的輸出波形如圖6所示。從圖中可以看出,在ap_start使能信號置1之后,經(jīng)過17個時鐘周期得到輸出結(jié)果。從開始輸出結(jié)果,到輸出完成,一共經(jīng)過234個時鐘周期,也就是2 340 ns,與公式(2)中計算結(jié)果相同。
卷積計算模塊的總體時延如表1所示,從表中可以看出,每次計算PE需要17個時鐘周期才能夠得到結(jié)果。在使用了流水化操作,并且達到了1級流水的目標之后,每個時鐘周期都會開啟一個新的循環(huán),PE無需等待到計算出結(jié)果就可以進行下一個循環(huán)。與圖6中的波形結(jié)果相同。
表2所示為卷積計算模塊的總體資源消耗,卷積計算的核心就是乘法運算。賽靈思xc7z020clg484-1型FPGA芯片內(nèi)置了DSP48核,可同時進行一組乘法和加法運算。根據(jù)卷積模塊的設(shè)計,每一個PE使用一個DPS48核進行乘加計算。在CHI為3,CHO為8的情況下,一共需要24個DPS48核,與表中使用資源情況相符。觸發(fā)器和查找表資源使用也較少,為之后擴大卷積計算模塊和設(shè)計卷積神經(jīng)網(wǎng)絡(luò)其余模塊預(yù)留了充足的資源。
3 結(jié)論
卷積神經(jīng)網(wǎng)絡(luò)中存在著大量的卷積計算,本文在資源使用情況較少的情況下,基于脈動陣列的運行方式,對并行展開的卷積計算模塊進行改進,然后通過Vivado HLS在賽靈思xc7z020clg484-1型FPGA芯片上進行實現(xiàn)。在后續(xù)的研究中,可以將脈動陣列與循環(huán)展開和循環(huán)平鋪等并行展開方式相結(jié)合,從提高運行速度與降低使用資源上進一步提升卷積計算模塊的性能。
參考文獻
[1] 張杰,隋陽,李強,等.基于卷積神經(jīng)網(wǎng)絡(luò)的火災(zāi)視頻圖像檢測[J].電子技術(shù)應(yīng)用,2019,45(4):34-38,44.
[2] 陳辰,嚴偉,夏珺,等.基于FPGA的深度學(xué)習(xí)目標檢測系統(tǒng)的設(shè)計與實現(xiàn)[J].電子技術(shù)應(yīng)用,2019,45(8):40-43,47.
[3] Zhang Xiaofan,Wang Junson,Zhu Chao,et al.DNN-Builder:an automated tool for building high-performance DNN hardware accelerators for FPGAs[C].Proceedings of the International Conference on Computer-Aided Design.ACM,2018.
[4] Zhang Chen,Li Peng,Sun Guangyu,et al.Optimizing fpga-based accelerator design for deep convolutional neural networks[C]. Proceedings of the 2015 ACM/SIGDA International Symposium on Field-Programmable Gate Arrays.ACM,2015.
[5] JOUPPI N P,YOUNG C,PATIL N,et al.In-datacenter performance analysis of a tensor processing unit[C].2017 ACM/IEEE 44th Annual International Symposium on Computer Architecture(ISCA).IEEE,2017.
[6] Chen Tianshi,Du Zidong,Sun Ninghui,et al.Diannao:a small-footprint high-throughput accelerator for ubiquitous machine-learning[C].ACM Sigplan Notices.ACM,2014:269-284.
[7] HU Y H,KUNG S Y.Systolic arrays.in:handbook of signal processing systems[M].Springer,Cham,2019:939-977.
[8] SANAULLAH A,HERBORDT M C.Unlocking performance-programmability by penetrating the Intel FPGA OpenCL Toolflow[C]. 2018 IEEE High Performance Extreme Computing Conference(HPEC).IEEE,2018.
[9] KUNG H T,LEISERSON C E.Systolic arrays(for VLSI)[C].Sparse Matrix Proceedings 1978,Society for Industrial and Applied Mathematics,1979.
[10] 王陽,陶華敏,肖山竹,等.基于脈動陣列的矩陣乘法器硬件加速技術(shù)研究[J].微電子學(xué)與計算機,2015,32(11):120-124.
作者信息:
王春林,譚克俊
(大連海事大學(xué) 信息科學(xué)技術(shù)學(xué)院,遼寧 大連116026)