2.1 Gem5环境搭建
核心内容:
-
✅ 系统要求
- Ubuntu 20.04/22.04 LTS
- 至少8GB RAM(建议16GB+)
- 50GB+ 磁盘空间
- Python 3.8+
-
✅ 依赖安装
基础依赖
sudo apt update
sudo apt install build-essential git m4 scons zlib1g zlib1g-dev
libprotobuf-dev protobuf-compiler libprotoc-dev libgoogle-perftools-dev
python3-dev python3-pip python3-six libboost-all-dev pkg-config可选依赖(用于完整功能)
sudo apt install libpng-dev libcairo2-dev python3-pydot libcanberra-gtk-module
libcanberra-gtk3-module libglib2.0-dev libpixman-1-dev
源码获取
# 克隆官方仓库
git clone https://github.com/gem5/gem5.git
cd gem5
# 切换到稳定版本(可选)
git checkout stable
编译构建
# 编译X86架构(最常用)
scons build/X86/gem5.opt -j$(nproc)
# 编译其他架构
scons build/ARM/gem5.opt -j$(nproc)
scons build/RISCV/gem5.opt -j$(nproc)
scons build/POWER/gem5.opt -j$(nproc)
# 编译调试版本(包含调试符号)
scons build/X86/gem5.debug -j$(nproc)
# 编译快速版本(无优化,用于调试)
scons build/X86/gem5.fast -j$(nproc)
验证安装
# 运行简单测试
./build/X86/gem5.opt configs/example/se.py --cmd=/bin/ls
# 查看帮助信息
./build/X86/gem5.opt --help
学习资料:
- 🌐 官方文档 :https://www.gem5.org/documentation/general_docs/building
- 📺 视频教程:Gem5官方YouTube频道 - "Getting Started with gem5"
- 📚 GitHub Wiki :https://github.com/gem5/gem5/wiki
常见问题:
- 编译失败:检查依赖是否完整,查看错误信息
- 内存不足:减少并行编译数(-j4而不是-j $ (nproc))
- 磁盘空间不足:清理旧的构建文件(scons -c)
2.2 Gem5架构理解
核心内容:
- ✅ SimObject系统
- 所有组件都是SimObject的子类
- 参数化配置机制
- 层次化对象结构
- ✅ 事件驱动机制
- EventQueue事件队列
- 事件调度与执行
- 时间推进机制
- ✅ CPU模型
- SimpleCPU:简单时序模型,快速但不精确
- TimingSimpleCPU:精确时序模型
- MinorCPU:简化乱序模型
- O3CPU:全功能乱序执行模型
- ✅ 内存系统
- Classic Memory System:传统内存系统
- Ruby Memory System:基于消息传递的一致性模型
- ✅ 缓存层次
- L1 Instruction/Data Cache
- L2 Cache
- 可配置的缓存参数(大小、关联度、块大小)
架构图:
SimObject (基类)
├── System
│ ├── CPU
│ │ ├── SimpleCPU
│ │ ├── TimingSimpleCPU
│ │ ├── MinorCPU
│ │ └── O3CPU
│ ├── Memory
│ ├── Cache
│ │ ├── L1ICache
│ │ ├── L1DCache
│ │ └── L2Cache
│ └── Bus/Interconnect
└── Device
源码结构:
gem5/
├── src/
│ ├── sim/ # 核心模拟器代码
│ ├── cpu/ # CPU模型
│ ├── mem/ # 内存系统
│ ├── dev/ # 设备模型
│ └── base/ # 基础设施
├── configs/ # 配置脚本
│ ├── example/ # 示例配置
│ └── common/ # 通用组件
└── tests/ # 测试用例
学习资料:
- 📚 官方架构文档 :https://www.gem5.org/documentation/general_docs/architecture/
- 📄 论文:"The gem5 simulator" (SIGARCH Computer Architecture News, 2011)
- 📺 视频:Gem5 Bootcamp 2022 - Architecture Overview
源码阅读建议:
- 从
src/sim/SimObject.py开始理解SimObject - 阅读
src/cpu/BaseCPU.py了解CPU基类 - 查看
src/mem/Cache.py理解缓存实现 - 阅读
configs/example/se.py学习配置脚本
2.3 配置脚本编写
核心内容:
- ✅ Python配置语法
- SimObject实例化
- 参数设置
- 对象连接
- ✅ 系统组件配置
- CPU配置
- 内存配置
- 缓存配置
- 总线配置
- ✅ 运行模式
- SE (System Call Emulation):系统调用仿真模式
- FS (Full System):完整系统仿真模式
基础配置示例:
# simple_config.py
import m5
from m5.objects import *
# 创建系统
system = System()
system.clk_domain = SrcClockDomain()
system.clk_domain.clock = '1GHz'
system.clk_domain.voltage_domain = VoltageDomain()
# 内存设置
system.mem_mode = 'timing'
system.mem_ranges = [AddrRange('512MB')]
# CPU设置
system.cpu = TimingSimpleCPU()
# 缓存设置
system.cpu.icache = L1ICache()
system.cpu.dcache = L1DCache()
# 连接缓存到CPU
system.cpu.icache_port = system.cpu.icache.cpu_side
system.cpu.dcache_port = system.cpu.dcache.cpu_side
# 内存总线
system.membus = SystemXBar()
# 连接缓存到总线
system.cpu.icache.mem_side = system.membus.cpu_side_ports
system.cpu.dcache.mem_side = system.membus.cpu_side_ports
# 内存控制器
system.mem_ctrl = MemCtrl()
system.mem_ctrl.dram = DDR3_1600_8x8()
system.mem_ctrl.dram.range = system.mem_ranges[0]
system.mem_ctrl.port = system.membus.mem_side_ports
# 连接系统端口
system.system_port = system.membus.cpu_side_ports
# SE模式设置
process = Process()
process.cmd = ['tests/test-progs/hello/bin/x86/linux/hello']
system.cpu.workload = process
system.cpu.createThreads()
# 实例化和运行
root = Root(full_system=False, system=system)
m5.instantiate()
print("Beginning simulation!")
exit_event = m5.simulate()
print(f"Exiting @ tick {m5.curTick()} because {exit_event.getCause()}")
多核配置示例:
# multicore_config.py
import m5
from m5.objects import *
from Caches import *
# 创建系统
system = System()
system.clk_domain = SrcClockDomain(clock='1GHz', voltage_domain=VoltageDomain())
system.mem_mode = 'timing'
system.mem_ranges = [AddrRange('2GB')]
# 创建4个CPU
system.cpu = [TimingSimpleCPU(cpu_id=i) for i in range(4)]
# 为每个CPU创建缓存
for cpu in system.cpu:
cpu.icache = L1ICache()
cpu.dcache = L1DCache()
cpu.icache_port = cpu.icache.cpu_side
cpu.dcache_port = cpu.dcache.cpu_side
# L2总线和缓存
system.l2bus = L2XBar()
system.l2cache = L2Cache()
# 连接所有CPU的L1缓存到L2总线
for cpu in system.cpu:
cpu.icache.mem_side = system.l2bus.cpu_side_ports
cpu.dcache.mem_side = system.l2bus.cpu_side_ports
# 连接L2总线到L2缓存
system.l2bus.mem_side_ports = system.l2cache.cpu_side
# 内存总线
system.membus = SystemXBar()
# 连接L2缓存到内存总线
system.l2cache.mem_side = system.membus.cpu_side_ports
# 内存控制器
system.mem_ctrl = MemCtrl()
system.mem_ctrl.dram = DDR3_1600_8x8()
system.mem_ctrl.dram.range = system.mem_ranges[0]
system.mem_ctrl.port = system.membus.mem_side_ports
# 系统端口
system.system_port = system.membus.cpu_side_ports
# SE模式设置
for i, cpu in enumerate(system.cpu):
process = Process()
process.cmd = ['tests/test-progs/hello/bin/x86/linux/hello']
cpu.workload = process
cpu.createThreads()
# 实例化和运行
root = Root(full_system=False, system=system)
m5.instantiate()
print("Beginning simulation!")
exit_event = m5.simulate()
print(f"Exiting @ tick {m5.curTick()} because {exit_event.getCause()}")
实践项目:
- ✅ 创建单核CPU系统并运行
- ✅ 创建双核CPU系统并运行
- ✅ 修改缓存参数观察性能变化
- ✅ 运行不同的测试程序(hello, mm, etc.)
学习资料:
- 📚 官方教程 :https://www.gem5.org/documentation/learning_gem5/part1/
- 📖 配置示例 :
configs/example/目录 - 📺 视频:Gem5 Bootcamp - Configuration Scripting