陸 松,蔣句平,任會峰
(1.無錫學(xué)院,江蘇 無錫 214105;2.國防科技大學(xué)計算機(jī)學(xué)院,湖南 長沙 410073)
處理器作為信息處理的引擎,推動了人類社會數(shù)字化、信息化和智能化的進(jìn)程。人們對處理器性能的追求永無止境。在特定領(lǐng)域的硬件加速,需要使用ASIC芯片、協(xié)處理器或加速卡來擴(kuò)展處理器功能[1]。過去由于指令集的封閉性,這些加速部件的設(shè)計和應(yīng)用軟件的開發(fā)通常滯后于處理器設(shè)計[2,3]。
Figure 2 RISC-V base opcode map,inst[1:0]=11
隨著開放指令集RISC-V的流行[4-6],其已應(yīng)用于IoT智能硬件[7]、嵌入式系統(tǒng)[8]、信號處理[9]、人工智能[10]、安全設(shè)備[11]及高性能計算[12-14]等不同領(lǐng)域。大量開源和商業(yè)IP軟核[15]的出現(xiàn),使RISC-V處理器的快速定制化成為可能,讓軟硬件協(xié)同設(shè)計更加高效,大幅縮短了軟硬件系統(tǒng)設(shè)計周期[16]。
本文基于FPGA設(shè)計了蜂鳥E203上[17,18]的計算向量內(nèi)積的自定義指令,以加速矩陣運算。按照增加自定義指令、擴(kuò)展ALU功能單元、連接控制信號和數(shù)據(jù)通路、FPGA原型驗證和應(yīng)用程序測試的流程開展了以下工作:
(1)在RV32IMAC指令集基礎(chǔ)上增加計算向量內(nèi)積的指令,確定指令類型和編碼;
(2)擴(kuò)展蜂鳥E203軟核ALU部件,實現(xiàn)向量內(nèi)積運算的硬件邏輯;
(3)連接控制信號和數(shù)據(jù)通路,完成向量內(nèi)積指令的譯碼、派遣、執(zhí)行、交付和寫回;
(4)完成自定義指令的功能仿真,并在FPGA平臺上進(jìn)行原型驗證;
(5)定制GCC編譯器,增加對向量內(nèi)積指令的支持,與硬件設(shè)計同步進(jìn)行軟件開發(fā)。
蜂鳥E203軟核是使用Verilog語言實現(xiàn)的,支持RV32IMAC指令集。每條指令由操作碼、功能碼和操作數(shù)組成,具有6種基本指令格式[4,17],如圖1所示,分別是:用于寄存器-寄存器操作的R型指令、用于短立即數(shù)和訪存load操作的I型指令、用于訪存store操作的S型指令、用于條件跳轉(zhuǎn)操作的B型指令、用于長立即數(shù)的U型指令和用于無條件跳轉(zhuǎn)的J型指令。
Figure 1 Instruction format for base 32-bit RISC-V
有2種擴(kuò)展RISC-V指令集的方法:
(1)模塊標(biāo)準(zhǔn)化方法。使用RISC-V的標(biāo)準(zhǔn)擴(kuò)展模塊,包括B、E、H、J、L、N、P、Q等多種可選擴(kuò)展[4]。
(2)在標(biāo)準(zhǔn)指令集基礎(chǔ)上加入定制指令。與ASIC芯片相似,指令集可裁剪,具有更高的性能,但需要注意與標(biāo)準(zhǔn)指令的編碼沖突問題。
為加速矩陣運算,本文采用了第2種方法,在RV32IMAC指令集基礎(chǔ)上引入一條向量內(nèi)積R型指令vec_inner_prod,選擇標(biāo)準(zhǔn)指令編碼空間(如圖2所示)中的一個保留編碼1101011作為向量內(nèi)積的指令操作碼,其指令格式如圖 3所示。
Figure 3 Instruction format for vec_inner_prod
蜂鳥E200系列是兩級流水線結(jié)構(gòu)[17],如圖4所示,指令的譯碼、執(zhí)行、交付和寫回均處于流水線的第2級,由EXU單元完成。
Figure 4 Two-stage pipeline of Hummingbird E203 IP
EXU的微架構(gòu)如圖5所示,其執(zhí)行過程如下:
(1)取指單元IFU通過IR寄存器將指令發(fā)送給EXU進(jìn)行譯碼;
(2)通過譯碼出的操作數(shù)寄存器索引來讀取Regfile;
(3)維護(hù)指令的相關(guān)性;
(4)將指令派遣給不同的運算單元執(zhí)行;
(5)交付指令;
(6)將運算結(jié)果寫回Regfile。
Figure 5 Microarchitecture of EXU in Hummingbird E203 IP
增加向量內(nèi)積指令需要對指令執(zhí)行路徑上的各個部件進(jìn)行擴(kuò)展,主要涉及“譯碼與派遣”部件、ALU、寄存器文件等。
待增加的向量內(nèi)積運算部件vec_mul用于計算向量A=[A0,A1,A2,A3]和B=[B0,B1,B2,B3]的內(nèi)積,向量長度為4,存放于寄存器中,其計算結(jié)果如式(1)所示:
result=A0×B0+A1×B1+
A2×B2+A3×B3
(1)
向量內(nèi)積運算部件vec_mul使用4個乘法器組成計算陣列,其邏輯結(jié)構(gòu)如圖6所示。
Figure 6 Logical structure of vec_mul unit
指令譯碼部件根據(jù)向量內(nèi)積指令中的操作碼和功能碼來產(chǎn)生控制信號,并發(fā)送至ALU部件的控制信號總線上,如圖 7中①所示。當(dāng)執(zhí)行的指令為vec_inner_prod時,譯碼部件產(chǎn)生相應(yīng)的operation選擇信號發(fā)送到ALU的多路選擇器,最后輸出向量內(nèi)積運算部件vec_mul的計算結(jié)果。
向量內(nèi)積運算部件需要掛接在ALU內(nèi)部,并將其輸入端口連接至寄存器X10~X17,如圖 7中②所示。
另外,為了防止與其它長指令目的寄存器之間有沖突,需要進(jìn)行數(shù)據(jù)相關(guān)性檢測,并記錄向量內(nèi)積指令,如圖7中③所示。
Figure 7 Control signals for vec-inner-prod
定制化RISC-V的驗證分為3個部分:硬件平臺的驗證[19]、交叉編譯環(huán)境的驗證[20]和應(yīng)用軟件的驗證。硬件平臺和交叉編譯環(huán)境的驗證用于保證硬件設(shè)計和軟件開發(fā)環(huán)境的正確性,應(yīng)用軟件的驗證用于測試軟硬件的性能。驗證流程如圖8所示,定制化的RISC-V處理器設(shè)計通過EDA工具Vivado生成配置FPGA的比特流文件;應(yīng)用測試程序通過定制化的交叉編譯器生成與硬件相匹配的二進(jìn)制可執(zhí)行文件;兩者加載到FPGA后即可在定制RISC-V處理器上運行二進(jìn)制應(yīng)用程序。
Figure 8 Validation procedure on FPGA
本文采用Perf-V Artix-7 35T開發(fā)板[21],如圖8所示,使用的板載FPGA型號為XC7A35T-1FTG256C,F(xiàn)PGA外部時鐘頻率為50 MHz。
操作系統(tǒng)為Ubuntu 16.04 LTS,硬件開發(fā)環(huán)境為Vivado 2018.3。
根據(jù)前述分析,在E203各部件對應(yīng)的Verilog代碼中添加向量內(nèi)積指令的相關(guān)運算和控制邏輯,其層次結(jié)構(gòu)如圖 9所示,原理如圖10所示。
Figure 9 Hierarchy of the customized RISC-V core
Figure 10 Schematic diagram of the customized RISC-V core
在Vivado中進(jìn)行綜合、布局布線(如圖11所示),最終生成配置FPGA的比特流文件并通過JTAG下載。未使用 FPGA DSP單元的情況下,增加向量內(nèi)積指令及相關(guān)控制邏輯會多使用FPGA內(nèi)9.3%的LUT硬件資源,增加向量內(nèi)積指令前后硬件資源占用情況如表1所示。
Figure 11 Floorplan of FPGA prototype
Table 1 Resource utilization comparison for customized/non-customized RISC-V
應(yīng)用測試程序必須使用定制化的交叉編譯器才能生成與硬件相匹配的二進(jìn)制可執(zhí)行文件。在基于64位x86架構(gòu)的Ubuntu 16.04 LTS主機(jī)上定制交叉編譯器的步驟如下:(1)根據(jù)自定義指令的操作碼計算指令碼、指令掩碼并描述指令格式;(2)將其加入到編譯器源代碼RISC-V的機(jī)器描述文件[22,23]中;(3)在主機(jī)上編譯支持定制RISC-V指令的交叉編譯器。
在開發(fā)板BSP(Board Support Package)[21,24]的支持下,可將C標(biāo)準(zhǔn)庫printf等函數(shù)輸出轉(zhuǎn)發(fā)到串口。測試程序以內(nèi)聯(lián)匯編的方式調(diào)用向量內(nèi)積計算匯編指令,該指令匯編助記符為vec_inner_prod,編譯產(chǎn)生的二進(jìn)制可執(zhí)行文件使用OpenOCD[25]通過USER JTAG下載到flash存儲器。
測試程序為三重循環(huán)的矩陣乘法運算,外層的兩重循環(huán)對應(yīng)于結(jié)果矩陣中的每個元素,內(nèi)層循環(huán)用于計算2個向量的內(nèi)積,未使用自定義向量內(nèi)積指令的C語言代碼如程序1所示。
程序1未使用向量內(nèi)積指令vec_inner_prod的矩陣乘法
for(i=0;i for(j=0;j for(k=0;k { c[i*C_COL+j]+=a[i*A_COL+k]*b[k*B_COL+j]; } 由于向量內(nèi)積指令的向量長度為4,因此需要改造上述程序1中的代碼,讓內(nèi)層循環(huán)中的每4個元素組成1個向量,即內(nèi)層循環(huán)以4為步長進(jìn)行遞增,如程序2代碼所示。對于長度不為4倍數(shù)的向量內(nèi)積,可通過補(bǔ)零處理使其長度成為4的倍數(shù)。 程序2使用向量內(nèi)積指令vec_inner_prod的矩陣乘法 for(i=0;i for(j=0;j for(k=0;k { asm volatile( "lw x10,%[a0]
lw x14,%[b0]
" "lw x11,%[a1]
lw x15,%[b1]
" "lw x12,%[a2]
lw x16,%[b2]
" "lw x13,%[a3]
lw x17,%[b3]
" "vec_inner_prod %[reg_output],x10,x14
" :[reg_output]"=r"(result) :[a0]"m"(a[i*A_COL+(k+0)]), [b0]"m"(b[(k+0)*B_COL+j]), [a1]"m"(a[i*A_COL+(k+1)]), [b1]"m"(b[(k+1)*B_COL+j]), [a2]"m"(a[i*A_COL+(k+2)]), [b2]"m"(b[(k+2)*B_COL+j]), [a3]"m"(a[i*A_COL+(k+3)]), [b3]"m"(b[(k+3)*B_COL+j]) :"x10","x11","x12","x13", "x14","x15","x16","x17" ); c[i*C_COL+j]+=result; } 對程序2最內(nèi)層循環(huán)代碼進(jìn)行了如下改造:使用內(nèi)嵌匯編指令,將2個向量分別載入到寄存器,然后執(zhí)行向量內(nèi)積指令 vec_inner_prod,運算結(jié)果保存在變量result中,最后將其累加到結(jié)果矩陣中相應(yīng)的元素上。 分別對程序1和程序2進(jìn)行交叉編譯生成目標(biāo)平臺的二進(jìn)制可執(zhí)行文件,兩者在FPGA平臺上的計算結(jié)果一致,對于不同規(guī)模的矩陣乘法,其所需時間如表2所示,最大加速比為7.6,最小加速比為5.3。 Table 2 Speedup of matrix multiplication on the customized RISC-V 本文基于FPGA在開源IP蜂鳥E203上通過增加自定義指令、擴(kuò)展ALU功能單元、連接控制信號和數(shù)據(jù)通路、FPGA原型驗證、定制交叉編譯環(huán)境和應(yīng)用程序測試的流程,設(shè)計了擴(kuò)展RV32IMAC指令集的向量內(nèi)積指令,實現(xiàn)了加速矩陣運算的定制化RISC-V處理器。對矩陣乘法測試程序上,定制化RISC-V處理器的計算性能有顯著提升,性能加速比達(dá)到了5.3~7.6。同時,基于定制化的交叉編譯器,軟件開發(fā)與硬件設(shè)計可同步進(jìn)行,大幅縮短了軟硬件協(xié)同設(shè)計周期。5 實驗結(jié)果
6 結(jié)束語