第二阶段:Gem5基础学习

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.)

学习资料

相关推荐
我想我不够好。2 小时前
坚持到习惯为止
学习·学习方法
三品吉他手会点灯2 小时前
STM32F103 学习笔记-21-串口通信(第4节)—串口发送和接收代码讲解(下)
笔记·stm32·单片机·嵌入式硬件·学习
U盘失踪了2 小时前
学习记录:requests Django登录测试脚本(解决CSRF、重定向问题)
笔记·python·学习·django·csrf
minglie12 小时前
人的性质辨析
学习
zhangrelay2 小时前
三分钟云课实践速通--线性代数--python版--矩阵
linux·笔记·python·学习·线性代数·ubuntu·矩阵
xuhaoyu_cpp_java3 小时前
Mybatis学习(四)
java·经验分享·笔记·学习·mybatis
不灭锦鲤3 小时前
网络安全学习第171天
学习·安全·web安全
艾莉丝努力练剑3 小时前
剑指巅峰,磨砺芳华:我的 CSDN 创作一周年深度总结
linux·运维·服务器·c++·学习
Chunyyyen5 小时前
【第四十二周】论文阅读
论文阅读·学习