沈凡凡,徐 超,张 军,何炎祥
(1. 南京审计大学 信息工程学院,江苏 南京 211815;2. 东华理工大学 软件学院,江西 南昌 330013;3. 武汉大学 计算机学院,湖北 武汉 430072)
在计算机体系结构课程实验教学中,缓存体系结构设计采用计算机硬件实验平台、实验箱、开发板,通过简单的模拟实验完成。然而,因为在硬件平台无法修改已有硬件体系结构,所以要从深层次理解缓存存储体系结构及其实现原理,仅利用硬件平台进行实验是远远不够的,需要借助模拟仿真器进行实验。
Gem5 是一款优秀的计算机系统结构模拟器。为了方便学生快速掌握该模拟器的使用方法,本文在分析Gem5 模拟器缓存存储体系结构和原理的基础上,提出多组利用Gem5 模拟器构建缓存存储体系结构的实验方法[1-2]。
Gem5 模拟器是一款高度可配置、集成多种指令集和多种CPU 模型的体系结构模拟器[3],它是集M5模拟器[4]和 GEMS 模拟器[5]中最优秀的部分而形成的。M5 模拟器是美国密西根大学开发的模拟架构,主要用于多种指令集和多种CPU 模型的模拟;GEMS模拟器由美国威斯康星大学开发的,能够灵活、详细地模拟存储器的层次结构,包括缓存一致性协议和片上网络等。
Gem5 目前支持多种指令集架构,并能在Alpha、ARM、SPARC 和X86 上进行全系统模拟。Gem5 可以加载操作系统,具备模拟乱序执行、分支预测、多核多线程、存储体系结构和片上网络等多种微体系结构[6-8],支持 classic 和 Ruby 存储模型,支持 Atomic Simple、Timing Simple、InOrder 和 O3 CPU 模型,可以在全系统模式(full system,FS)和系统调用模式(syscall emulation,SE)下执行,如图1 所示。
图1 CPU 模型和存储模型
Gem5 的源代码遵循BSD 开源协议,用户可以修改和重新发布代码。Gem5 拥有友好的使用文档和社区支持,非常有利于高校学生学习和使用[9]。
图2 为Gem5 模拟器源代码结构。build_opts 定义了 ARM、X86 和 RISCV 等体系结构的默认设置。configs 包含一系类模拟器配置脚本文件,主要用Python 编写,是修改模拟器配置文件参数的关键部分,会经常用到。ext 依赖于Gem5 但不是Gem5 的一部分,一般很少用到。src 是Gem5 源代码的关键部分,包含计算机体系结构各部分的详细代码,其中$GEM5_DIR/src/mem/cache 是本文缓存存储体系实验所必须掌握的部分,也是需要重点关注的部分。system 描述模拟系统的固件和引导信息。tests 包含回归测试程序。util 包含常用脚本和一些辅助程序[7,10]。
图2 Gem5 模拟器源代码结构
Gem5 编译安装成功后,会生成 build 和 m5out文件夹。模拟器运行的测试结果和配置信息将记录在m5out 文件夹中。
要使用Gem5 模拟器,首先必须理解Gem5 的工作原理和执行流程,其次是根据需要修改对应的模块。Gem5 初始化函数调用过程[11]如图 3 所示。当在模拟器中运行 hello 程序($GEM5_DIR/build/ARM/gem5.opt configs/example/se.py -c tests/test-progs/hello/bin/arm/linux/hello)时,Gem5 模拟器执行的入口函数在$GEM5_DIR/src/sim/main.cc 文件中;然后依次调用m5Main 函数进行初始化,调用PyRun_String 函数传入SE 模式和二进制文件;在SE 模式下运行二进制文件,其中涉及 System 函数和 Simulation.run 函数:System 函数初始化硬件配置信息,Simulation.run 启动模拟过程。最后初始化C++构造函数。
图3 Gem5 初始化函数调用过程
若要深入学习和修改某个模块时,如CPU 或存储模块,需要阅读该模块代码,理解其执行和访问流程,根据需要修改相关代码完成模拟实验。
为探讨缓存存储系统的实验方法,需要重点关注Gem5 模拟器中的$GEM5_DIR/src/mem/cache 文件夹中的文件,包括 tags、replacement_policies、prefetch等描述信息。tags 中描述了组相连的信息;replacement_policies 中描述了缓存替换策略,包括LRU、FIFO 和BIP 等算法;prefetch 描述了缓存数据预期的方法。
在缓存模块中,首先分析cache_blk.hh 文件,理解缓存的组织结构;然后分析base.cc 文件,理解缓存的访问控制流程;最后分析lru_rp.cc 文件,理解缓存的替换策略的实现方式。在实验过程中,可以根据需要修改缓存体系结构以及缓存访问控制方法。
在Gem5 中,通过参数命令可以指定CPU 的配置,例如配置 2 核 1 GHz、4 核 2 GHz 的 CPU,涉及-n 和--cpu-clock 选项。
(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 种方法可以配置缓存:一是在配置文件中直接修改对应的参数值$GEM5_DIR/configs/common/Caches.py,这种方法比较直观;二是通过参数命令指定,比如配置二级缓存的容量和组相联度,可通过--l2_size 和--l2_assoc 选项指定,具体如下:
(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 中,可以配置不同的基准测试程序,用于评价实验的效果。例如采用PARSEC 测试集[12]中的streamcluster,可以采用如下脚本命令实现,关键选项为--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
以获取缓存读操作的访问信息为例,可通过如下步骤实现。
步骤一: 在文件$GEM5_DIR/src/mem/cache/SConscript 中添加 DebugFlag('myflag');
步骤二: 在文件$GEM5_DIR/src/mem/cache/base.cc 中添加 #include debug/myflag.hh,然后在access 函数中添加一下语句:
步骤三:在 Gem5 运行命令中添加调试选项—debug-flag=myflag,即可获取缓存读操作的访问信息。
Gem5 模拟器的缓存存储体系实验性能测试参数配置如下:
(1)处理器。配置为 2 核 CPU,ARM 架构,主频800 MHz,每个CPU 包含,1 个一级私有缓存和1个共享二级缓存。
(2)一级私有缓存。容量32 KB,4 路组相连,访问时间为1 个周期,LRU 缓存替换算法。
(3)二级共享缓存。容量为512 KB,8 路组相连,访问时间为8 个周期,LRU 缓存替换算法。
(4)主存。主存大小为256 MB,访问时间为65个周期。
使用PARSEC 测试集[12]对实验性能进行了测试。使用simsmall 作为输入集。
在Gem5 目录下执行如下脚本命令:
在$GEM5_DIR/m5out/stats.txt 文件中记录着测试程序运行的时间,其结果如表1 所示。
表1 测试程序执行时间
从以上测试结果可以看出:每个测试程序所需的执行时间不同,x264 执行的时间最长,需要4.45 s;blackscholes 执行的时间最短,只需要0.37 s。每当修改缓存存储体系结构时,系统的性能也将随之改变。因此在实验的过程中要合理地配置参数和修改缓存存储体系结构。
本文提出的基于Gem5 模拟器的缓存存储体系实验方法,为计算机存储系统的学习提供了一种低成本、高效率的实验操作方案。学生可以在学校的实验室中安装 Gem5,也可以离开实验室在自己的台式机或笔记本上安装 Gem5,从而降低了学习门槛,提高了学生实践的灵活性,为计算机存储体系结构的理论和实验教学提供了新途径。