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

学习资料

常见问题

  • 编译失败:检查依赖是否完整,查看错误信息
  • 内存不足:减少并行编译数(-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/             # 测试用例

学习资料

源码阅读建议

  1. src/sim/SimObject.py开始理解SimObject
  2. 阅读src/cpu/BaseCPU.py了解CPU基类
  3. 查看src/mem/Cache.py理解缓存实现
  4. 阅读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()}")

实践项目

  1. ✅ 创建单核CPU系统并运行
  2. ✅ 创建双核CPU系统并运行
  3. ✅ 修改缓存参数观察性能变化
  4. ✅ 运行不同的测试程序(hello, mm, etc.)

学习资料

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐