孫逸峰 王曉玲 錢 杰
北京航天自動控制研究所,北京 100854
隨著信息技術(shù)的飛速發(fā)展,數(shù)字信號處理(Digital Signal Processing,簡稱DSP)技術(shù)應(yīng)運(yùn)而生并得到迅速發(fā)展。目前應(yīng)用較為廣泛的DSP芯片是美國Taxas公司生產(chǎn)的TMS320系列的DSP處理器[1]。高速處理器的應(yīng)用一方面大大提升了嵌入式系統(tǒng)的性能,另一方面卻增加了軟件測試的難度。針對高速處理器嵌入式軟件測試構(gòu)建目標(biāo)碼測試環(huán)境時面臨的2個難題:1)難以實(shí)現(xiàn)測試數(shù)據(jù)的注入與獲取;2)難以采集動態(tài)測試目標(biāo)碼覆蓋信息。全數(shù)字仿真測試環(huán)境在軟件測試中的應(yīng)用很好地解決了上述問題。全數(shù)字仿真測試環(huán)境是使用軟件仿真的方式構(gòu)造嵌入式軟件運(yùn)行所需的硬件環(huán)境及外部數(shù)據(jù)源,構(gòu)成全數(shù)字嵌入式軟件運(yùn)行環(huán)境,利用對運(yùn)行環(huán)境的高度可控性,可以完成測試中所需數(shù)據(jù)的采集、存儲和分析工作,并可以全面監(jiān)控被測軟件的運(yùn)行狀態(tài)[2]。
虛擬內(nèi)核的研制是搭建全數(shù)字仿真測試環(huán)境的關(guān)鍵,其運(yùn)行效率影響著全數(shù)字仿真測試環(huán)境的性能。以TMS320VC33為例,真實(shí)處理器內(nèi)核執(zhí)行每條指令都需要經(jīng)過取指、譯碼、讀操作數(shù)和執(zhí)行四級流水,采用軟件仿真的方式實(shí)現(xiàn)這些步驟十分復(fù)雜,仿真一級流水通常需要數(shù)條甚至于數(shù)百條指令,如果再加上流水線停頓周期,虛擬內(nèi)核的運(yùn)行速度大概只有真實(shí)處理器內(nèi)核的幾百分之一[3]。流水線仿真優(yōu)化設(shè)計(jì)對虛擬內(nèi)核運(yùn)行效率的提高有重要的意義。本文以TMS320系列的DSP處理器TMS320VC33為例研究虛擬內(nèi)核流水線的仿真優(yōu)化設(shè)計(jì)方法。
TMS320VC33采用了4級流水線的工作方式,即一條指令分為取指、譯碼、讀操作數(shù)和執(zhí)行4個階段。每個階段的任務(wù)如下:
1)取指階段:從寄存器中取指令字并更新程序計(jì)數(shù)器PC的值;
2)譯碼階段:對指令字進(jìn)行譯碼并產(chǎn)生地址;
3)讀操作數(shù)階段:從存儲器或寄存器中讀操作數(shù);
4)執(zhí)行階段:從寄存器中讀出操作數(shù)后,執(zhí)行相應(yīng)的操作,并向目的地址寫結(jié)果[4]。
任何一條指令都必須經(jīng)過上述4個階段的處理。圖1說明了流水線的結(jié)構(gòu),圖中W,X,Y,Z代表具體指令,在第m個周期,這4個階段處于完全并行狀態(tài),即完全重疊在一起,從而進(jìn)入正常的流水線作業(yè)流程[5]。
圖1 TMS320VC33處理器流水線結(jié)構(gòu)
流水線仿真設(shè)計(jì)主要存在以下2個難點(diǎn):
1)真實(shí)處理器內(nèi)核指令執(zhí)行過程中,流水線各階段并行執(zhí)行,而在虛擬內(nèi)核中是串行順序仿真,如果指令正向推進(jìn),每個階段執(zhí)行過后將指令推進(jìn)到下一個階段都需要額外的緩沖區(qū),這就需要耗費(fèi)大量的內(nèi)存空間;
2)流水線取指階段負(fù)責(zé)產(chǎn)生指令的地址,在碰到分支指令時,順序仿真首先實(shí)現(xiàn)取指,即對第一個分支的指令進(jìn)行取指,而此時分支判斷還未執(zhí)行,未獲得程序的跳轉(zhuǎn)目標(biāo),就會導(dǎo)致錯誤的數(shù)據(jù)注入流水線。出現(xiàn)這種情況需預(yù)先判斷是否存在錯誤,然后清空流水線,這些操作會影響虛擬內(nèi)核運(yùn)行效率。
針對上述2個問題,在流水線仿真設(shè)計(jì)中應(yīng)采用倒序流水線仿真。倒序流水線仿真就是在仿真流水線時按照真實(shí)處理器內(nèi)核流水的倒序進(jìn)行仿真,先仿真執(zhí)行階段,之后依次是讀操作數(shù)階段、譯碼階段及取指階段。整個虛擬內(nèi)核的運(yùn)行由1個循環(huán)體構(gòu)成,循環(huán)體中包含四級流水線的倒序仿真,每循環(huán)1次就代表1個時鐘周期。
While(1)
{
Execute();//執(zhí)行階段仿真
ReadReg();//讀寄存器階段仿真
Decode();//譯碼階段仿真
Fetch();//取指階段仿真
If(execute_end) break;//程序執(zhí)行結(jié)束,退出循環(huán)體
}
倒序流水線仿真不僅可以減少系統(tǒng)規(guī)模還可以提高虛擬內(nèi)核的運(yùn)行效率。
1)采用倒序仿真可以有效節(jié)省內(nèi)存空間,減小系統(tǒng)規(guī)模
理論上每1個時鐘周期四級流水線都有指令在執(zhí)行,由于讀操作數(shù)階段不對指令本身進(jìn)行操作,只是從存儲器和寄存器中讀取數(shù)據(jù),所以在流水線仿真的討論中暫不考慮這一階段。圖2為流水線順序仿真示意圖,t時刻指令n處于取指階段,同一時鐘周期下的譯碼階段正在對指令n+1進(jìn)行譯碼,而執(zhí)行階段正在對指令n+2進(jìn)行執(zhí)行操作。
流水線仿真過程中需要設(shè)計(jì)1個數(shù)據(jù)結(jié)構(gòu)保存譯碼結(jié)果,以備后續(xù)的執(zhí)行階段使用。當(dāng)流水線正在執(zhí)行n指令時,n+1指令在譯碼階段需要開辟一塊內(nèi)存空間利用數(shù)據(jù)結(jié)構(gòu)保存譯碼結(jié)果。同一時鐘周期下流水線執(zhí)行n指令需要使用譯碼結(jié)果,就要保留上一個周期n指令處于譯碼階段時所開辟的內(nèi)存空間。這樣就需要2塊內(nèi)存空間來保存相應(yīng)的數(shù)據(jù),而流水線倒序仿真時可有效地避免這種情況。
圖2 流水線順序仿真
如圖3所示,在倒序仿真的情況下執(zhí)行先于譯碼,在t時刻,流水線執(zhí)行n指令,譯碼n+1指令,此時開辟內(nèi)存空間,利用數(shù)據(jù)結(jié)構(gòu)保存指令n+1的譯碼結(jié)果。下一個時鐘周期執(zhí)行n+1指令時所需要的譯碼結(jié)果就可以從數(shù)據(jù)結(jié)構(gòu)中直接獲得,而本周期n指令執(zhí)行所需要的譯碼結(jié)果來自上一個周期n指令的譯碼階段。所以,每個時鐘周期譯碼階段只需要開辟一塊內(nèi)存空間用于存儲譯碼結(jié)果。由此可見,在流水線倒序仿真比順序仿真可以節(jié)省近50%的內(nèi)存空間。
圖3 流水線倒序仿真
2)采用倒序仿真符合指令跳轉(zhuǎn)需要,可以提高虛擬內(nèi)核的運(yùn)行效率
如果是順序仿真,在碰到分支指令時,首先進(jìn)行取指,即對第一個分支中的指令進(jìn)行取指,而此時分支判斷還未執(zhí)行,未獲得程序的跳轉(zhuǎn)目標(biāo),就會導(dǎo)致錯誤的數(shù)據(jù)注入流水線。防止這種錯誤只能靠分支判斷執(zhí)行后再判斷跳轉(zhuǎn)地址與取指產(chǎn)生地址是否相同,如果不相同要清空流水線,這一系列操作都會導(dǎo)致流水線仿真的效率降低。
如果是倒序仿真就可以更好地保證跳轉(zhuǎn)指令的正確執(zhí)行,因?yàn)榈剐蛄魉€依次是執(zhí)行、讀操作數(shù)、譯碼和取指,在執(zhí)行階段后,分支判斷已經(jīng)執(zhí)行,那么取指階段就可以及時獲得正確的跳轉(zhuǎn)目標(biāo),從而防止錯誤的數(shù)據(jù)注入流水線,避免了地址判斷和清空流水線等一系列操作,從而提高虛擬內(nèi)核的運(yùn)行效率。
根據(jù)“二八原理”:在程序執(zhí)行過程中,20%的代碼完成了80%的工作,嵌入式軟件中通常包含了大量需要重復(fù)執(zhí)行的代碼[6],指令的重復(fù)執(zhí)行需要不斷重復(fù)地進(jìn)行譯碼操作,而譯碼階段主要包括指令的識別、指令類型的確定以及指令間相關(guān)性的檢測[7],是一個復(fù)雜度較高的步驟。如果在仿真過程中,對譯碼階段不進(jìn)行特殊處理,會浪費(fèi)大量時間,限制仿真的速度。為了提高譯碼階段的效率,可以將譯碼的結(jié)果緩存起來,譯碼過程將轉(zhuǎn)變?yōu)椴檎揖彺嬷惺欠癜g碼指令字的譯碼結(jié)果。若存在,則直接取出譯碼結(jié)果進(jìn)入下一級流水;否則,進(jìn)行譯碼,并將譯碼結(jié)果放入譯碼緩存中。若譯碼緩存已滿,則使用某種緩存替換算法替換掉緩存中的一個已有項(xiàng)。
綜上所述,基于譯碼緩存策略對流水線譯碼階段進(jìn)行優(yōu)化設(shè)計(jì)。在首次執(zhí)行代碼段時,利用數(shù)據(jù)結(jié)構(gòu)把譯碼的結(jié)果保存起來,如圖4(a)所示。圖2(b)為譯碼緩存中保存的一個譯碼結(jié)果,以指令A(yù)DDI R0,R1,R2為例,譯碼后的指令包括a1,a2和a3共3個操作數(shù)指針,它們指向虛擬的寄存器。f是函數(shù)指針,譯碼后指向相應(yīng)指令的功能模擬函數(shù)do_add(),該函數(shù)完成不進(jìn)位加法指令的運(yùn)算,并把結(jié)果寫回到目的操作數(shù)。譯碼結(jié)果存儲在譯碼緩存中,該緩存的結(jié)構(gòu)和原理與硬件指令Cache基本相同。每條指令進(jìn)入譯碼階段時,首先查找譯碼緩存中是否存在該指令所對應(yīng)的譯碼結(jié)果,若查找命中,即可直接進(jìn)入執(zhí)行階段?;谧g碼緩存策略的流水線仿真設(shè)計(jì)可以在一定程度上省去昂貴的譯碼開銷,提高流水線的仿真效率。
圖4 譯碼緩存策略存儲結(jié)構(gòu)示意圖
雖然譯碼緩存策略可以降低指令譯碼操作的重復(fù)性,局部范圍內(nèi)實(shí)現(xiàn)1次譯碼多次執(zhí)行,但是流水線仿真依然將大部分時間花在了譯碼上。如果可以將循環(huán)體中的譯碼操作移到循環(huán)體外執(zhí)行,即先對目標(biāo)代碼進(jìn)行譯碼并保存中間結(jié)果,隨后根據(jù)此中間結(jié)果直接運(yùn)行循環(huán)體,那么這個流水線仿真的效率將大大提高。
于是在仿真流水線時將譯碼階段前移,在目標(biāo)文件加載時一次性對目標(biāo)二進(jìn)制代碼進(jìn)行譯碼,譯出指令中的操作碼,從指令中提取出如源、目地寄存器編號、立即操作數(shù)值、確定每條指令模擬函數(shù)地址,并用數(shù)據(jù)結(jié)構(gòu)將上述結(jié)果存儲起來,形成預(yù)譯碼產(chǎn)生的中間代碼[8],如圖5所示。由于每條中間代碼指令已經(jīng)包含操作碼和操作數(shù),仿真執(zhí)行時可以將譯碼階段省去,直接從保存中間代碼的數(shù)據(jù)結(jié)構(gòu)中取出中間代碼指令,完成流水線操作,在全局范圍內(nèi)實(shí)現(xiàn)了一次譯碼,多次執(zhí)行。譯碼操作被獨(dú)立了出來,因此實(shí)際執(zhí)行目標(biāo)代碼的時間大大縮短,流水線的仿真效率得到了較大提高。
圖5 預(yù)譯碼策略示意圖
流水線仿真優(yōu)化設(shè)計(jì)很大程度上影響整個虛擬內(nèi)核的運(yùn)行效率。上述優(yōu)化策略從不同角度對TMS320VC33流水線的仿真效率進(jìn)行提高,但要最大程度上加快虛擬內(nèi)核的運(yùn)行速度,需要提出流水線仿真優(yōu)化設(shè)計(jì)的最優(yōu)方案,如圖6所示。
圖6 TMS320VC33流水線仿真優(yōu)化設(shè)計(jì)方案
TMS320VC33流水線仿真優(yōu)化設(shè)計(jì)方案基于倒序流水線仿真,在目標(biāo)程序加載過程中使用預(yù)譯碼策略一次性對目標(biāo)二進(jìn)制代碼進(jìn)行譯碼,得到譯碼結(jié)果,并將其保存為有指針指向的中間代碼。指令進(jìn)入倒序流水的譯碼階段時直接從保存中間代碼的數(shù)據(jù)結(jié)構(gòu)中取出中間代碼指令,完成流水線操作,并將取出的中間代碼指令保存在譯碼緩存中。再次譯碼過程將轉(zhuǎn)變?yōu)椴檎揖彺嬷惺欠癜g碼指令字的譯碼結(jié)果。若存在,則直接取出譯碼結(jié)果進(jìn)入下一級流水;否則,查詢保存中間代碼的數(shù)據(jù)結(jié)構(gòu),并將譯碼結(jié)果放入譯碼緩存中。整個優(yōu)化設(shè)計(jì)方案能有效地減少流水線譯碼階段的開銷,加快流水線執(zhí)行速度,提高虛擬內(nèi)核運(yùn)行效率。
本文探討了倒序流水線仿真、譯碼緩存策略以及預(yù)譯碼策略等優(yōu)化設(shè)計(jì)方法對TMS320VC33虛擬內(nèi)核流水線仿真效率的提高,并在此基礎(chǔ)上提出了虛擬內(nèi)核流水線仿真方案。
TMS320VC33流水線仿真模塊的設(shè)計(jì)與優(yōu)化,為DSP處理器虛擬內(nèi)核流水線仿真提供了技術(shù)參考,為進(jìn)一步研制其他高性能處理器虛擬內(nèi)核,并實(shí)現(xiàn)虛擬內(nèi)核產(chǎn)品化,并為搭建相應(yīng)的全數(shù)字仿真測試環(huán)境奠定基礎(chǔ)。
[1] 張錫寧.數(shù)字信號處理器的發(fā)展及應(yīng)用[J].雷達(dá)與對抗,1998:36-39.
[2] 周濤.航天型號軟件測試[M].宇航出版社,1999.
[3] 桑勝田,王進(jìn)祥,趙新曙.采用動態(tài)譯碼緩存的高速指令集模擬器[J].計(jì)算機(jī)工程,2006,32(8):248-249.(SANG Shengtian,WANG Jinxiang,ZHAO Xinshu.High Performance Instruction Set Simulator Using Dynamic Decode Cache[J].Computer Engineering,2006,32(18):248-249.)
[4] TMS320VC33 Digital Signal Processor[Z].Texas Instruments,1999.
[5] TMS320C3x User’s Guide[Z].Texas Instruments,1991.
[6] 林方全,等.DSP指令集仿真器優(yōu)化技術(shù)研究[J].科學(xué)技術(shù)與工程,2011,11(29):7152-7153.
[7] 武曉島,等.預(yù)譯碼技術(shù)專利引證分析[J].中國集成電路,2009,(118):84-85.
[8] 關(guān)小川,陳朝暉,黨紀(jì)紅.快速SPARC V7指令集模擬器的設(shè)計(jì)方法[J].計(jì)算機(jī)工程與設(shè)計(jì),2011,32(2):532-533.(GUAN Xiao-chuan,CHEN Zhao-hui,DANG Ji-hong.Design of Fast SPARC V7 Instruction Set Simulator[J].Computer Engineering and Design,2011,32(2):532-533.)