沈凡凡,徐 超,張 軍,何炎祥
(1. 南京審計(jì)大學(xué) 信息工程學(xué)院,江蘇 南京 211815;2. 東華理工大學(xué) 軟件學(xué)院,江西 南昌 330013;3. 武漢大學(xué) 計(jì)算機(jī)學(xué)院,湖北 武漢 430072)
在計(jì)算機(jī)體系結(jié)構(gòu)課程實(shí)驗(yàn)教學(xué)中,緩存體系結(jié)構(gòu)設(shè)計(jì)采用計(jì)算機(jī)硬件實(shí)驗(yàn)平臺(tái)、實(shí)驗(yàn)箱、開發(fā)板,通過簡單的模擬實(shí)驗(yàn)完成。然而,因?yàn)樵谟布脚_(tái)無法修改已有硬件體系結(jié)構(gòu),所以要從深層次理解緩存存儲(chǔ)體系結(jié)構(gòu)及其實(shí)現(xiàn)原理,僅利用硬件平臺(tái)進(jìn)行實(shí)驗(yàn)是遠(yuǎn)遠(yuǎn)不夠的,需要借助模擬仿真器進(jìn)行實(shí)驗(yàn)。
Gem5 是一款優(yōu)秀的計(jì)算機(jī)系統(tǒng)結(jié)構(gòu)模擬器。為了方便學(xué)生快速掌握該模擬器的使用方法,本文在分析Gem5 模擬器緩存存儲(chǔ)體系結(jié)構(gòu)和原理的基礎(chǔ)上,提出多組利用Gem5 模擬器構(gòu)建緩存存儲(chǔ)體系結(jié)構(gòu)的實(shí)驗(yàn)方法[1-2]。
Gem5 模擬器是一款高度可配置、集成多種指令集和多種CPU 模型的體系結(jié)構(gòu)模擬器[3],它是集M5模擬器[4]和 GEMS 模擬器[5]中最優(yōu)秀的部分而形成的。M5 模擬器是美國密西根大學(xué)開發(fā)的模擬架構(gòu),主要用于多種指令集和多種CPU 模型的模擬;GEMS模擬器由美國威斯康星大學(xué)開發(fā)的,能夠靈活、詳細(xì)地模擬存儲(chǔ)器的層次結(jié)構(gòu),包括緩存一致性協(xié)議和片上網(wǎng)絡(luò)等。
Gem5 目前支持多種指令集架構(gòu),并能在Alpha、ARM、SPARC 和X86 上進(jìn)行全系統(tǒng)模擬。Gem5 可以加載操作系統(tǒng),具備模擬亂序執(zhí)行、分支預(yù)測(cè)、多核多線程、存儲(chǔ)體系結(jié)構(gòu)和片上網(wǎng)絡(luò)等多種微體系結(jié)構(gòu)[6-8],支持 classic 和 Ruby 存儲(chǔ)模型,支持 Atomic Simple、Timing Simple、InOrder 和 O3 CPU 模型,可以在全系統(tǒng)模式(full system,F(xiàn)S)和系統(tǒng)調(diào)用模式(syscall emulation,SE)下執(zhí)行,如圖1 所示。

圖1 CPU 模型和存儲(chǔ)模型
Gem5 的源代碼遵循BSD 開源協(xié)議,用戶可以修改和重新發(fā)布代碼。Gem5 擁有友好的使用文檔和社區(qū)支持,非常有利于高校學(xué)生學(xué)習(xí)和使用[9]。
圖2 為Gem5 模擬器源代碼結(jié)構(gòu)。build_opts 定義了 ARM、X86 和 RISCV 等體系結(jié)構(gòu)的默認(rèn)設(shè)置。configs 包含一系類模擬器配置腳本文件,主要用Python 編寫,是修改模擬器配置文件參數(shù)的關(guān)鍵部分,會(huì)經(jīng)常用到。ext 依賴于Gem5 但不是Gem5 的一部分,一般很少用到。src 是Gem5 源代碼的關(guān)鍵部分,包含計(jì)算機(jī)體系結(jié)構(gòu)各部分的詳細(xì)代碼,其中$GEM5_DIR/src/mem/cache 是本文緩存存儲(chǔ)體系實(shí)驗(yàn)所必須掌握的部分,也是需要重點(diǎn)關(guān)注的部分。system 描述模擬系統(tǒng)的固件和引導(dǎo)信息。tests 包含回歸測(cè)試程序。util 包含常用腳本和一些輔助程序[7,10]。

圖2 Gem5 模擬器源代碼結(jié)構(gòu)
Gem5 編譯安裝成功后,會(huì)生成 build 和 m5out文件夾。模擬器運(yùn)行的測(cè)試結(jié)果和配置信息將記錄在m5out 文件夾中。
要使用Gem5 模擬器,首先必須理解Gem5 的工作原理和執(zhí)行流程,其次是根據(jù)需要修改對(duì)應(yīng)的模塊。Gem5 初始化函數(shù)調(diào)用過程[11]如圖 3 所示。當(dāng)在模擬器中運(yùn)行 hello 程序($GEM5_DIR/build/ARM/gem5.opt configs/example/se.py -c tests/test-progs/hello/bin/arm/linux/hello)時(shí),Gem5 模擬器執(zhí)行的入口函數(shù)在$GEM5_DIR/src/sim/main.cc 文件中;然后依次調(diào)用m5Main 函數(shù)進(jìn)行初始化,調(diào)用PyRun_String 函數(shù)傳入SE 模式和二進(jìn)制文件;在SE 模式下運(yùn)行二進(jìn)制文件,其中涉及 System 函數(shù)和 Simulation.run 函數(shù):System 函數(shù)初始化硬件配置信息,Simulation.run 啟動(dòng)模擬過程。最后初始化C++構(gòu)造函數(shù)。

圖3 Gem5 初始化函數(shù)調(diào)用過程
若要深入學(xué)習(xí)和修改某個(gè)模塊時(shí),如CPU 或存儲(chǔ)模塊,需要閱讀該模塊代碼,理解其執(zhí)行和訪問流程,根據(jù)需要修改相關(guān)代碼完成模擬實(shí)驗(yàn)。
為探討緩存存儲(chǔ)系統(tǒng)的實(shí)驗(yàn)方法,需要重點(diǎn)關(guān)注Gem5 模擬器中的$GEM5_DIR/src/mem/cache 文件夾中的文件,包括 tags、replacement_policies、prefetch等描述信息。tags 中描述了組相連的信息;replacement_policies 中描述了緩存替換策略,包括LRU、FIFO 和BIP 等算法;prefetch 描述了緩存數(shù)據(jù)預(yù)期的方法。
在緩存模塊中,首先分析cache_blk.hh 文件,理解緩存的組織結(jié)構(gòu);然后分析base.cc 文件,理解緩存的訪問控制流程;最后分析lru_rp.cc 文件,理解緩存的替換策略的實(shí)現(xiàn)方式。在實(shí)驗(yàn)過程中,可以根據(jù)需要修改緩存體系結(jié)構(gòu)以及緩存訪問控制方法。
在Gem5 中,通過參數(shù)命令可以指定CPU 的配置,例如配置 2 核 1 GHz、4 核 2 GHz 的 CPU,涉及-n 和--cpu-clock 選項(xiàng)。
(1)配置 2 核 CPU:$GEM5_DIR/build/ARM/gem5.opt$GEM5_DIR/configs/example/se.py -n 2 --cpu-clock=1 GHz
(2)配置 4 核 CPU:$GEM5_DIR/build/ARM/gem5.opt$GEM5_DIR/configs/example/se.py -n 4 --cpu-clock=2 GHz
在Gem5 中,有2 種方法可以配置緩存:一是在配置文件中直接修改對(duì)應(yīng)的參數(shù)值$GEM5_DIR/configs/common/Caches.py,這種方法比較直觀;二是通過參數(shù)命令指定,比如配置二級(jí)緩存的容量和組相聯(lián)度,可通過--l2_size 和--l2_assoc 選項(xiàng)指定,具體如下:
(1)128 KB、8 路組相連。
$GEM5_DIR/build/ARM/gem5.opt$GEM5_DIR/co nfigs/example/se.py--caches --l1d_size=32kB --l1d_assoc=2 --l1i_size=32kB --l1i_assoc=2--l2cache --l2_size=128kB --l2_assoc=8
(2)256 KB、16 路組相連。
$GEM5_DIR/build/ARM/gem5.opt$GEM5_DIR/co nfigs/example/se.py--caches --l1d_size=32kB --l1d_assoc=2 --l1i_size=32kB --l1i_assoc=2 --l2cache --l2_size=256kB --l2_assoc=16
在Gem5 中,可以配置不同的基準(zhǔn)測(cè)試程序,用于評(píng)價(jià)實(shí)驗(yàn)的效果。例如采用PARSEC 測(cè)試集[12]中的streamcluster,可以采用如下腳本命令實(shí)現(xiàn),關(guān)鍵選項(xiàng)為--script:
$GEM5_DIR/build/ARM/gem5.opt
$GEM5_DIR/configs/example/fs.py
--kernel=$BINARY_DIR/vmlinux.vexpress_gem5_v1_64--script= $GEM5_DIR/streamcluster_16c_simsmall_ckpts.rcS
以獲取緩存讀操作的訪問信息為例,可通過如下步驟實(shí)現(xiàn)。
步驟一: 在文件$GEM5_DIR/src/mem/cache/SConscript 中添加 DebugFlag('myflag');
步驟二: 在文件$GEM5_DIR/src/mem/cache/base.cc 中添加 #include debug/myflag.hh,然后在access 函數(shù)中添加一下語句:

步驟三:在 Gem5 運(yùn)行命令中添加調(diào)試選項(xiàng)—debug-flag=myflag,即可獲取緩存讀操作的訪問信息。
Gem5 模擬器的緩存存儲(chǔ)體系實(shí)驗(yàn)性能測(cè)試參數(shù)配置如下:
(1)處理器。配置為 2 核 CPU,ARM 架構(gòu),主頻800 MHz,每個(gè)CPU 包含,1 個(gè)一級(jí)私有緩存和1個(gè)共享二級(jí)緩存。
(2)一級(jí)私有緩存。容量32 KB,4 路組相連,訪問時(shí)間為1 個(gè)周期,LRU 緩存替換算法。
(3)二級(jí)共享緩存。容量為512 KB,8 路組相連,訪問時(shí)間為8 個(gè)周期,LRU 緩存替換算法。
(4)主存。主存大小為256 MB,訪問時(shí)間為65個(gè)周期。
使用PARSEC 測(cè)試集[12]對(duì)實(shí)驗(yàn)性能進(jìn)行了測(cè)試。使用simsmall 作為輸入集。
在Gem5 目錄下執(zhí)行如下腳本命令:

在$GEM5_DIR/m5out/stats.txt 文件中記錄著測(cè)試程序運(yùn)行的時(shí)間,其結(jié)果如表1 所示。

表1 測(cè)試程序執(zhí)行時(shí)間
從以上測(cè)試結(jié)果可以看出:每個(gè)測(cè)試程序所需的執(zhí)行時(shí)間不同,x264 執(zhí)行的時(shí)間最長,需要4.45 s;blackscholes 執(zhí)行的時(shí)間最短,只需要0.37 s。每當(dāng)修改緩存存儲(chǔ)體系結(jié)構(gòu)時(shí),系統(tǒng)的性能也將隨之改變。因此在實(shí)驗(yàn)的過程中要合理地配置參數(shù)和修改緩存存儲(chǔ)體系結(jié)構(gòu)。
本文提出的基于Gem5 模擬器的緩存存儲(chǔ)體系實(shí)驗(yàn)方法,為計(jì)算機(jī)存儲(chǔ)系統(tǒng)的學(xué)習(xí)提供了一種低成本、高效率的實(shí)驗(yàn)操作方案。學(xué)生可以在學(xué)校的實(shí)驗(yàn)室中安裝 Gem5,也可以離開實(shí)驗(yàn)室在自己的臺(tái)式機(jī)或筆記本上安裝 Gem5,從而降低了學(xué)習(xí)門檻,提高了學(xué)生實(shí)踐的靈活性,為計(jì)算機(jī)存儲(chǔ)體系結(jié)構(gòu)的理論和實(shí)驗(yàn)教學(xué)提供了新途徑。