文/梁成豪
如今,高級語言(如C語言)已經成為大量被應用于系統、應用軟件的開發。軟件的性能好壞在對其進行大規模應用時在設計極差的地方可以被宏觀的觀察出來,但是也很難定位到問題所在,即便是可以定位到問題所在,也很難分析得很細微以達到對軟件相應設計較差的代碼進行改進的目的。如今有一些軟件性能分析工具如linux的perf,以及C語言庫頭文件
實際上,實際系統中很難有完全精確的工具來對應用程序的性能進行不間斷的精確追蹤。這樣的精確追蹤。而計算機體系結構仿真器是一個很好的解決方案。
計算機體系結構仿真器主要是用來在系統層面探究和優化計算機體系結構參數設計的工具。通常而言,它們詳細建模了某一計算機體系結構內部部件,諸如CPU執行部件、cache等。軟件通過編譯可以在仿真工具上進行運行,運行之后仿真器給出運行結果統計,從而驗證軟件在某一組體系結構參數(通常包括cache相聯性、內存讀寫端口數等)的性能。本文利用SimpleScalar(SS)為基礎來開發MIPS架構軟件性能探究工具。
SS是由Todd Austin開發的一個用于模擬計算機體積結構諸如計算單元、緩存與內存系統、分支猜測等部件在內的開源仿真器。它本身攜帶了幾個處理器模型,仿真速度從快到慢,精度從低到高依次有sim-fast、simsafe、sim-prof i le、以及sim-outorder等。本文以sim-outorder作為依托,因為其模擬程度最詳細,囊括了整數、浮點寄存器、2級可配置cache、哈佛架構并且擁有亂序執行部件、預測執行部件等現代處理器常見架構。流水線方面,它詳細模擬了MIPS諸如取指、譯碼、執行、訪存和回寫在內的5級流水。
對于sim-outorder來講,SS以ruu_fetch()、ruu_dispatch()、ruu_commit()等幾個關鍵函數實現5級流水。在指令解碼方面,machine.def文件以宏定義的方式匯集了每個指令的指令名稱、指令碼、執行方式、涉及功能部件等信息。
可執行文件的格式標識了可執行文件的類型,不同的語言以及不同的執行環境一般會產生不同類型的可執行文件。如Linux平臺下可執行文件格式主要有兩種:ELF和COFF。前者是現今Linux平臺下最為流行的可執行文件格式,通常由GCC編譯的可執行文件,其格式就是ELF。系統通常系統根據文件頭頭幾個字節來區分兩者的不同。而ECOFF格式是應用于MIPS的可執行文件格式。SS所應用的是一種和ECOFF兼容的可執行文件格式。
C語言是高級語言,通常情況下,每句C語言最終都被編譯為不止一句匯編語言。要完成C每行代碼和程序計數器(PC)的對應,首先就要完成C語言和匯編語言的對應。
SS支持的是ECOFF格式的可執行為文件,因此要下載其自己的binutils工具鏈來完成。可以在編譯應用程序時加上-g選項來進行編譯。在編譯之后,利用objdump命令對.o文件進行處理,并加入--disassemble選項進行反匯編,-l進行行數顯示,--source進行源代碼顯示。將產生的文件導入新的文件,這個文件就記錄了C代碼行號和匯編代碼的對應關系。由于文件顯示信息過多,利用額外的程序對該文件進行正則匹配處理,之拿出行號和匯
編操作碼的對應即可。考慮到后面的需要,只需要提取出來匯編指令操作碼即可。
SS的指令由64位構成。前32位是操作碼,后32位是操作數。分別由8個16進制數表示。ECOFF將可執行文件分為.text、.rdata、.data、.sdata、.sbss和 .bss六個段。其中 .text段表示代碼段;.rdata表示只讀的數據段;.data段表示已被初始化的可讀寫數據段;.sdata表示;.sbss表示;.bss表示未初始化的數據段。
SS在加載可執行文件的時候。首先會讀取可執行文件的文件頭信息,里面涵蓋了7個信息,其中包含了魔數(f_magic)、段的個數(f_cscns)、文件建立時間(f_timdat)、符號表相對于文件的偏移量(f_symptr)、符號表條目個數(f_nsyms)、可選頭部長度(f_opthdr)以及文件標志(f_flags)。
除此之外,還有可選文件頭以及各個段的頭。每個段的頭所涵蓋的10個信息有:
段名稱(s_name);段物理地址(s_paddr);段虛擬地址(s_vaddr);段大小(s_size);段數據相對于文件的偏移量(s_scnptr);重定位信息偏移量(s_relptr);行信息偏移量(s_lnnptr);重定為條目數(s_nreloc);行信息條目數(s_nlnno);標志(s_flags)。
要拿到匯編操作碼和PC指針的對應關系,需要分析TEXT段的內容。由于SS是以s_vaddr為基礎將代碼段整體放入仿真器內存的,因此首先根據s_flags定位到TEXT段,然后在另一個文件中記錄出每8個字節提取前4個字節作為匯編操作碼,以及與此相對應的PC值(即每個指令對應的s_vaddr的值)。這樣可以得到操作碼和PC指針的對應關系文件。
在得到C代碼行數和匯編操作碼對應的關系文件以及匯編操作碼和PC指針的對應關系文件后,便可以得到C語言行數和PC指針的對應關系。這樣的記錄方式是對可執行文件和執行環境沒有侵入的,即沒有在可執行文件中加入任何的記錄標志,同時也沒有對cache進行數據污染。
SS自帶有執行過程各部件訪問統計,但是沒有每周期的數據,為了更好地分析可執行文件的執行過程,可以額外加入每周期的處理器各部件訪問統計。在每周期開始時,將統計變量設為初始值,然后在執行過程中在程序不同地方進行每個統計變量的加操作,在一周期執行完畢后,將結果記錄,同時再將統計變量設為初始值,以便下個周期進行統計。
在執行的每個周期都進行統計和記錄,這樣就形成了PC和統計量的對應關系文件。
由于在此之前提取了每周期C語言行數和PC指針的對應關系文件以及每周期PC指針和該周期處理器各部件訪問統計,因此可以最終得到記錄每周期C語言代碼和該周期處理器各部件訪問統計的文件。將此文件在MATLAB等工具中進行可視化處理,便可以直觀分析軟件執行過程中每行C語言代碼所造成的各部件訪問情況,從而達到指導軟件優化的目的。
由于現階段程序性能分析工具會侵入目標程序的自身或者執行環境,不能做到精確分析軟件自身的問題。為了給目標分析程序提供一個非侵入式的純凈執行環境以便更好地分析程序的執行性能和瓶頸,本文以SimpleScalar仿真器為基礎,實現了一個可以與匯編、C程序每執行周期嚴格對應的應用程序性能分析工具。本文也提出了一個較好的方法,即利用原本用來進行處理器體系結構探索的仿真工具來進行目標指令集和架構的軟件性能探索和研究。如果有其它指令集或架構的周期精確體系結構仿真器,利用此方法,依然可以探索該平臺下的軟件性能。
參考文獻
[1]徐恒陽,安虹,劉玉,周偉.Perf在龍芯2F上的設計與實現[J].計算機工程,2011,19(37):236-238.
[2]SimpleScalar Architectural Research Tool Set,version 3.0.www.simplescalar.com.
[3]俞甲子,石凡,潘愛民.程序員的自我修養——鏈接、裝載與庫[M].電子工業出版社,2009.