郭 輝,黃立波,鄭 重,隋兵才,王永文
(國防科技大學(xué)計算機學(xué)院,湖南 長沙 410073)
眾所周知,處理器設(shè)計和制造是當今世界上最復(fù)雜的項目之一。整個處理器設(shè)計和制造的過程包含體系結(jié)構(gòu)設(shè)計、處理器前端設(shè)計、處理器后端設(shè)計、功能驗證和性能評估等一系列設(shè)計流程。因此,不僅處理器的設(shè)計和制造需要巨大的資金投入,而且一款處理器從開始設(shè)計到最終投向市場,整個項目研發(fā)的周期通常需要幾年的時間。最近,得益于RISC-V架構(gòu)處理器的快速發(fā)展,硬件敏捷開發(fā)方法逐漸成為一種流行的趨勢。采用敏捷開發(fā)方法設(shè)計處理器在一定程度上簡化了體系結(jié)構(gòu)設(shè)計、處理器前端設(shè)計和功能驗證,從而縮短了處理器的研發(fā)周期。但是,處理器前端代碼在sign-off之前的性能評估和驗證始終是一個相當耗費時間的流程,進而會拖延整個項目的進度。
通常來講,工業(yè)界和學(xué)術(shù)界常常使用一些標準的測試程序集來評估處理器的性能。這些標準測試程序集分別從不同角度對整個處理器系統(tǒng)進行評價,包括計算峰值、訪存延遲、分支預(yù)測和片上緩存等。例如,SPEC CPU2000/2006/2017是一系列通用處理器標準測試程序集,主要測試處理器運行通用應(yīng)用程序的能力,而LINPACK則主要用來評估處理器的浮點計算能力,常常被用來作為超級計算機系統(tǒng)的一個評價指標。測試人員通過完整地運行整個測試程序集可以獲得相應(yīng)的測試報告。通過測試報告,測試人員可以清楚地了解處理器的性能,也可以比較不同處理器間的性能差異。
處理器原型系統(tǒng)的早期性能驗證一方面可以幫助設(shè)計人員盡早發(fā)現(xiàn)處理器設(shè)計和實現(xiàn)階段存在的缺陷,另一方面也可以幫助設(shè)計人員探索處理器體系結(jié)構(gòu)可優(yōu)化的空間。目前,通用處理器的設(shè)計及研發(fā)前期的主要驗證平臺包括軟件模擬器[1 - 3]、FPGA原型系統(tǒng)[4 - 6]和硬件仿真器[7,8]等。相比于真實的處理器芯片,這些平臺的一個共同特點是運行頻率非常低,從幾兆赫茲到幾十兆赫茲不等。在這種情況下,一個在真實芯片上運行一天的測試程序集,在這些處理器驗證測試平臺上,常常需要運行幾周或幾個月的時間。這就導(dǎo)致設(shè)計人員無法及時分析RTL實現(xiàn)的處理器性能,延長了處理器性能驗證的周期,進而拖延了整個項目進度。因此,在處理器原型系統(tǒng)上完整地運行測試程序集進行性能測試是不可行的。
另一方面,雖然已經(jīng)有一些軟件模擬器開始支持快速精確的處理器性能評估[9,10],但是軟件模擬器的實現(xiàn)與實際RTL設(shè)計代碼存在巨大的差異,導(dǎo)致通過軟件模擬器獲得的性能測試結(jié)果無法反映RTL實現(xiàn)的處理器的真實性能。因此,實現(xiàn)快速精確的早期處理器性能評估是實現(xiàn)硬件敏捷開發(fā)的一項迫切需求。
程序分析領(lǐng)域的研究發(fā)現(xiàn),程序執(zhí)行具有明顯的階段性特征,并且很多執(zhí)行階段會在整個程序執(zhí)行過程中不斷重復(fù)出現(xiàn)。因此,如果能夠在測試前充分分析測試程序,并抽取出每個階段的指令序列,那么就可以只在處理器原型系統(tǒng)上執(zhí)行這些指令序列,從而減少程序執(zhí)行時間。在測試完各階段的所有指令序列后,可以根據(jù)每個階段指令序列的性能以及該階段在程序中所占比重推測出處理器原型系統(tǒng)運行整個程序的性能?;谶@個思想,本文提出一種快速準確的處理器原型系統(tǒng)性能評估方法Proto-Perf。
本文的主要貢獻如下所示:
(1)本文提出一種基于動態(tài)程序分析和基本塊向量聚類分析的處理器原型系統(tǒng)性能評估方法Proto-Perf,該方法可以顯著縮短程序測試的時間,同時可以提供較高精確度的性能測試結(jié)果。
(2)Proto-Perf使用簡單,并且可以跨不同處理器驗證平臺工作。
(3)實驗結(jié)果表明,Proto-Perf可以在非常短的時間內(nèi)精確地測算出處理器原型系統(tǒng)的性能。
本文的其余部分為:第2節(jié)介紹快速精確的通用處理器FPGA原型系統(tǒng)性能評估方法的研究動機,第3節(jié)介紹Proto-Perf性能評估方法,第4節(jié)介紹Proto-Perf在處理器FPGA原型系統(tǒng)上的實驗測試結(jié)果,最后第5節(jié)對全文進行總結(jié)。
實現(xiàn)快速精確的通用處理器FPGA原型系統(tǒng)性能評估的首要任務(wù)是減少測試程序集的運行時間。一種最簡單的降低性能評估時間開銷的方法是減小測試數(shù)據(jù)集的大小,比如對于SPEC CPU2006的程序,使用test規(guī)模的數(shù)據(jù)集進行測試,或者減少測試程序集中測試程序的數(shù)量。那么,完整的測試程序集性能就需要依據(jù)縮減后的測試程序集的性能進行推算。Phansalkar等人[11]提出了一種使用統(tǒng)計學(xué)方法建立SPEC CPU2006測試子集的測試方法。這種方法雖然一定程度上減少了程序集的測試時間,但是測試結(jié)果的精確度卻下降了很多。而且,即使測試子集中的程序數(shù)量相比于完整測試程序集減少了很多,但是對于處理器FPGA原型系統(tǒng)來說,完整測試該子集仍然需要大量的時間。
目前,一部分通用處理器制造商,比如Intel和ARM,已經(jīng)在軟件模擬器上廣泛使用SimPoint[12]機制來分析和預(yù)測下一代處理器體系結(jié)構(gòu)的性能提升。該方法的主要思想是通過程序分析將原應(yīng)用程序的指令序列劃分為多個指令序列片段,從中選擇出一些有代表性的指令序列作為測試樣例,最后通過在軟件模擬器上執(zhí)行這些測試樣例來獲得測試程序的性能。每個程序的測試樣例都是根據(jù)程序本身的執(zhí)行特點從具有相似程序行為的指令序列中抽取出來的,因此這些測試樣例在程序行為的表現(xiàn)上與原應(yīng)用程序幾乎一致,從而保證模擬器只需執(zhí)行這些測試樣例就可以在短時間內(nèi)獲得精確的性能數(shù)據(jù)。但是,使用軟件模擬器進行性能評估只能在處理器項目研發(fā)前期作為探索處理器架構(gòu)設(shè)計的一種方法,并不能檢測處理器前端設(shè)計中是否引入了性能缺陷。另外,在芯片流片之前,驗證處理器原型系統(tǒng)的性能、進一步優(yōu)化處理器設(shè)計并確保設(shè)計的處理器能夠達到預(yù)期性能指標是非常必需的工作。因此,設(shè)計一種面向硬件驗證平臺的快速精確的性能分析方法是非常重要的。
本節(jié)主要介紹面向通用處理器原型驗證系統(tǒng)的性能評估方法Proto-Perf。Proto-Perf主要包含生成代碼基本塊向量、篩選程序指令流片段、生成程序指令流片段檢查點和計算處理器原型驗證系統(tǒng)性能等步驟。
Proto-Perf性能評估方法降低程序測試時間開銷的基本思想與Intel和ARM在軟件模擬的性能評估中應(yīng)用的方法相似,即執(zhí)行應(yīng)用程序部分指令流序列而不是整個應(yīng)用程序。因此,從應(yīng)用程序指令流中篩選出來的指令流序列的覆蓋率就決定了最終使用Proto-Perf方法計算出來的處理器性能的精確度。在程序分析領(lǐng)域,動態(tài)程序分析是一項比較成熟的技術(shù),它在預(yù)先執(zhí)行整個應(yīng)用程序的過程中捕獲應(yīng)用程序的動態(tài)行為,從而可以掌握應(yīng)用程序的行為特點。代碼基本塊是一段連續(xù)的程序指令序列,只有一個入口指令和一個出口指令,是程序分析中構(gòu)成指令流序列最基本的單元。通過分析每個指令流序列的代碼基本塊構(gòu)成就可以確定每個指令流序列的程序行為特點,因此具有相似代碼基本塊構(gòu)成的指令流序列就可以劃分到一類。
基于以上思想,Proto-Perf性能評估方法將應(yīng)用程序切分為多個具有相同指令流長度的指令流序列,這些指令流序列由多個代碼基本塊構(gòu)成。因此,Proto-Perf采用代碼基本塊向量的方式來記錄每個指令流序列中所包含的代碼基本塊,如圖1所示。每一個代碼基本塊向量都記錄了所代表的指令流序列包含了哪些代碼基本塊以及每個代碼基本塊在該指令流序列中執(zhí)行的次數(shù)。圖1以代碼基本塊的形式展示了一個代碼指令流序列,并假設(shè)整個程序中一共有6個代碼基本塊。從圖1中可知,這段代碼包含3個代碼基本塊(B1、B2和B3)。根據(jù)執(zhí)行序列就可以很容易得到代碼基本塊向量。圖2為Proto-Perf性能評估方法的整體基本流程,其中生成代碼基本塊向量的步驟中代碼塊向量表記錄了指令流序列P1~P6的代碼塊向量。目前,已經(jīng)有許多開源的工具支持開發(fā)代碼基本塊向量生成的功能,例如Pin[13]和Valgrind[14]等。
Figure 1 Generating code basic block vector from code basic block sequence圖1 由代碼基本塊序列生成代碼基本塊向量
通過記錄代碼基本塊向量,Proto-Perf基本掌握了每個指令流序列的程序行為特征。如果有2個代碼指令流序列代碼基本塊向量的特征相似,那么這2個指令流序列就具有相似的程序行為特征。因此,Proto-Perf性能評估方法采用聚類分析(K-Means)算法[15]將應(yīng)用程序中具有相似程序行為特征的指令流序列進行歸類。具體方法如下所示:首先使用線性隨機投影方法降低代碼基本塊向量的維度。由于一個應(yīng)用程序通常包含成千上萬個基本塊,導(dǎo)致代碼基本塊向量維度過高,從而導(dǎo)致聚類算法復(fù)雜度加大。因此,在聚類分析之前先降低代碼基本塊向量的維度可以加速聚類分析。其次,設(shè)定最大的聚類數(shù)量K,并在[1,K]內(nèi)使用不同k值進行K-Means算法分析。第3步,從不同k值的分析結(jié)果中選擇最優(yōu)的結(jié)果對代碼基本塊向量進行分類。最優(yōu)結(jié)果的選擇標準是,既要滿足貝葉斯信息準則BIC(Bayesian Information Criterion)[16],同時還要求k值盡量小,也就是說,在所有結(jié)果中選擇最接近已知最高得分的最小k值分類。最后,歸類完成后,從每一類中選擇出一個指令流序列構(gòu)成應(yīng)用程序的樣本集合。該樣本集合幾乎具有所有的應(yīng)用程序行為特征。圖2篩選程序指令流片段的步驟中首先根據(jù)代碼基本塊向量將指令流序列進行聚類,劃分為4大類:P1和P4,P2和P6,P3,P5。然后,從每一大類中選擇出一個指令流序列構(gòu)成最終的樣本集合。
Figure 2 Workflow of Proto-Perf圖2 Proto-Perf性能評估方法基本流程
由于篩選出的指令流序列不是連續(xù)的指令流,而是廣泛分布在應(yīng)用程序指令流的不同階段,因此需要記錄執(zhí)行樣本集合中指令流序列前的程序狀態(tài),這樣才能保證在處理器原型系統(tǒng)上只需運行樣本集合中指令流序列,同時還使得Proto-Perf性能評估方法能夠在不同的原型系統(tǒng)上使用。圖2篩選程序指令流片段的步驟中樣本集合由指令流序列P1、P3、P5和P6構(gòu)成,所以指令流序列P1、P3、P5是不連續(xù)的。一旦這些指令流序列的檢查點生成之后,Proto-Perf性能評估方法可以在不同的處理器原型系統(tǒng)上重復(fù)使用這些檢查點,無需再重新生成檢查點。
然而,由于檢查點生成過程需要完整執(zhí)行整個程序,因此考慮到在處理器原型驗證系統(tǒng)上生成檢查點需要巨大的時間開銷,Proto-Perf性能評估方法使用與被測試處理器原型系統(tǒng)具有相似架構(gòu)的真實處理器芯片來生成檢查點,以此來縮短檢查點生成時間。
Proto-Perf性能評估方法使用檢查點恢復(fù)技術(shù)將樣本集合中的指令流序列在處理器原型系統(tǒng)驗證平臺上執(zhí)行,并記錄處理器執(zhí)行每個指令流序列時平均每條指令執(zhí)行需要的周期數(shù)CPI。另外,在篩選程序指令流片段的步驟中,Proto-Perf會記錄樣本集合中每個指令流序列對整個程序性能所貢獻的比重。依據(jù)以上2個數(shù)據(jù),Proto-Perf可以計算處理器原型系統(tǒng)的平均每條指令執(zhí)行需要的周期數(shù)CPI=∑CPIi*Weighti,其中CPIi為處理器執(zhí)行樣本集合中第i個指令流序列時平均每條指令執(zhí)行需要的周期數(shù),Weighti為樣本集合中第i個指令流序列對整個程序性能所貢獻的比重。
本節(jié)介紹使用Proto-Perf性能評估方法在處理器FPGA原型系統(tǒng)上進行測試的實驗環(huán)境和實驗結(jié)果。
本文實驗測試中使用的通用處理器FPGA原型系統(tǒng)是正在進行的一項處理器開發(fā)項目,其工作頻率設(shè)定為25 MHz。另外,我們選取了一個已經(jīng)量產(chǎn)并且與正在開發(fā)的處理器具有相同體系結(jié)構(gòu)的處理器芯片(2.6 GHz)用作生成程序指令流片段檢查點的平臺。此外,我們基于一些開源軟件工具構(gòu)建了Proto-Perf性能評估方法的工具鏈。其中,使用Valgrind作為生成代碼基本塊向量的工具;使用SimPoint軟件篩選程序指令流片段;使用Linux操作系統(tǒng)的CRIU工具[17]在真實芯片平臺上生成指令流序列檢查點,以及在處理器FPGA原型系統(tǒng)上恢復(fù)指令流序列執(zhí)行。
SPEC CPU2006測試程序集[18]是一個獲得了工業(yè)界和學(xué)術(shù)界廣泛認可的專門用來測試和評價通用處理器、內(nèi)存子系統(tǒng)和編譯器性能的綜合基準測試套件。該測試集包含了12個整數(shù)測試程序和19個浮點測試程序。將測試集完整地在處理器上運行一遍,可以獲得處理器的SPEC得分,并且可以將產(chǎn)生的結(jié)果報告上傳到SPEC官方網(wǎng)站。然而,若要獲得準確的處理器性能,就必須使用Ref測試數(shù)據(jù)集作為測試數(shù)據(jù)。目前由于FPGA工作頻率較低,完整測試所有程序需要較高的時間成本。因此,作為驗證Proto-Perf性能評估方法有效性的實驗,本文對11個應(yīng)用程序分別使用Proto-Perf性能評估方法和完整運行程序的方式進行了測試。其中11個應(yīng)用程序的詳細情況如下所示:
(1)456.hmmer是用C語言實現(xiàn)的基于隱馬爾可夫模型的生物序列分析程序;
(2)400.perlbench是用C語言編寫的Perl語言解釋器;
(3)445.gobmk是用C語言實現(xiàn)的一個圍棋游戲;
(4)401.bzip2是用C語言實現(xiàn)的壓縮/解壓縮程序;
(5)471.omnetpp是用C++語言實現(xiàn)的離散事件仿真器OMNeT++;
(6)464.h264ref是用C語言編寫的視頻壓縮程序;
(7)437.leslie3d是用Fortran 90語言實現(xiàn)的計算湍流的計算流體力學(xué)程序;
(8)434.zeusmp是用Fortran 77語言編寫的統(tǒng)一磁場的3D沖擊波模擬程序;
(9)436.cactusADM是用Fortran 90和ANSI C語言實現(xiàn)的物理廣義相對論;
(10)481.wrf是用Fortran 90和C語言實現(xiàn)的WRF模型;
(11)465.tonto是用Fortran 95語言實現(xiàn)的量子晶體學(xué)的Hartree-Fock波函數(shù)。
圖3展示了分別采用上述2種測試方法得到的處理器FPGA原型系統(tǒng)運行SPEC CPU2006應(yīng)用程序的CPI和Proto-Perf性能評估方法相比于實際運行得到CPI的誤差。 Proto-Perf的誤差主要來自以下3個方面:首先,Proto-Perf的主要性能誤差來源于方法本身使用指令流片段集合來計算整個應(yīng)用程序的性能。Proto-Perf為了縮短FPGA系統(tǒng)的運行時間,對每個應(yīng)用程序進行分析并根據(jù)程序執(zhí)行特征篩選出可以反映應(yīng)用程序性能的指令流片段集合。由于指令流片段集合并不能完全代表整個應(yīng)用程序的行為,因此通過指令流片段集合得到的性能數(shù)據(jù)必然會在一定程度上損失精確度。其次,Proto-Perf在生成和恢復(fù)檢查點時會引入一些誤差。Proto-Perf的指令流片段使用執(zhí)行的指令數(shù)來設(shè)置檢查點的位置,但是由于CRIU在生成檢查點時需要執(zhí)行CRIU checkpoint程序,這就導(dǎo)致最終生成的檢查點與實際需要產(chǎn)生檢查點的位置之間存在一定偏差。同理,Proto-Perf恢復(fù)檢查點后需要繼續(xù)執(zhí)行一段程序來計算該指令流片段的CPI,然而恢復(fù)檢查點需要執(zhí)行CRIU restore程序,同樣會帶來檢查點的偏差。不過,通過設(shè)置warmup等手段可以減小這部分誤差。最后,Proto-Perf分別使用一款已上市的處理器和一個正在研發(fā)的處理器FPGA原型系統(tǒng)來分別生成和執(zhí)行指令流片段集合。雖然這2款處理器在體系架構(gòu)上非常相似,但是微體系結(jié)構(gòu)層次上存在的一些區(qū)別還是會導(dǎo)致程序行為的不同,進而使得生成的指令流片段集合與程序在處理器FPGA原型系統(tǒng)上表現(xiàn)的特點稍微不一致,從而引入部分誤差。實驗結(jié)果表明,與完整運行程序得到的CPI相比,使用Proto-Perf性能評估方法計算得到的CPI產(chǎn)生的誤差非常小。在11個測試程序中,平均絕對誤差為1.53%,其中最大絕對誤差為7.86%。
Figure 3 CPI of processor prototype system tested by Proto-Perf and running the program completely圖3 使用Proto-Perf性能評估方法和完整運行程序的方式測試處理器原型驗證系統(tǒng)的CPI
圖4展示了在配置不同K值(30/20/10)的情況下,Proto-Perf為11個應(yīng)用程序生成的檢查點總數(shù)以及測試性能得到的平均誤差。從圖4中可以看出,隨著K值從30下降到10,生成的檢查點總數(shù)呈現(xiàn)出明顯的下降趨勢,而測試性能得到的平均誤差出現(xiàn)明顯的上升。這是因為隨著生成的檢查點數(shù)減少,篩選出來的檢查點無法更全面地覆蓋程序執(zhí)行行為,從而導(dǎo)致測試得到的性能與實際性能偏差增大。但是,從圖4中還可以看出,隨著K值從30下降到10,性能平均誤差增長幅度會減小。這是因為生成的檢查點數(shù)下降間接地減少了生成和恢復(fù)檢查點的次數(shù),從而減少了Proto-Perf來自這方面的誤差。
Figure 4 Total number of checkpoints generated and average error rate tested by Proto-Perf with different maximum K value圖4 配置不同的K值,Proto-Perf為11個應(yīng)用程序生成的檢查點總數(shù)和測試的平均性能誤差
表1比較了11個應(yīng)用程序在處理器FPGA原型系統(tǒng)驗證平臺上分別采用完整運行的方式和Proto-Perf方法的運行時間。實驗結(jié)果表明,在驗證平臺工作頻率設(shè)定在25 MHz的情況下,Proto-Perf方法的運行時間顯著低于完整運行應(yīng)用程序的時間。
Table 1 Comparison time of running applications on processor prototype system directly with Proto-Perf method
從表1中還可以看出,雖然有的程序完整運行時間比較接近,但是使用Proto-Perf方法運行的時間會相差幾倍。這是因為Proto-Perf方法的運行時間主要與每個應(yīng)用程序的檢查點數(shù)量、恢復(fù)檢查點后執(zhí)行的指令條數(shù)和處理器執(zhí)行該程序的CPI有關(guān)。在實際中,恢復(fù)檢查點后執(zhí)行的指令條數(shù)在本次實驗中固定為109條,因此執(zhí)行時間只與檢查點數(shù)量和處理器執(zhí)行該應(yīng)用程序的CPI相關(guān)。例如,437.leslie3d和436.cactusADM 2個應(yīng)用程序完整執(zhí)行時間相近,但Proto-Perf的執(zhí)行時間相差了4.9×。這是因為437.leslie3d的檢查點有21個,而436.cactusADM只有5個。另外,雖然481.wrf和465.tonto生成的檢查點數(shù)量一樣,但是Proto-Perf執(zhí)行481.wrf和465.tonto得到的CPI分別為1.52和0.91,因此導(dǎo)致Proto-Perf執(zhí)行481.wrf的時間反而比執(zhí)行465.tonto的時間長。
本文提出一種快速精確的通用處理器原型系統(tǒng)性能評估方法Proto-Perf。Proto-Perf性能評估方法通過將應(yīng)用程序指令流劃分為多個指令流片段,從這些指令流片段中選擇出能夠代表程序特性的指令流片段作為樣本集合,并在處理器原型系統(tǒng)的驗證平臺上運行這些指令流片段,從而得到處理器原型系統(tǒng)的CPI。實驗結(jié)果表明,與完整運行程序得到的CPI相比,使用Proto-Perf性能評估方法的平均絕對誤差為1.53%,并且所有應(yīng)用程序在驗證平臺上的運行時間顯著下降。