当前位置: 首页 > news >正文

GEM5学习(5): ARM 架构功耗仿真

运行脚本

基于gem5提供的脚本,启动功耗仿真。实际工作中应该不会用gem5进行功耗的仿真吧,Cadence和Synopsys好像都有配套的的功耗建模工具。

事先要配置好 IMG_ROOT的环境变量

./build/ARM/gem5.opt configs/example/arm/fs_power.py   \--caches  \--bootloader="$IMG_ROOT/binaries/boot.arm" \--kernel="$IMG_ROOT/binaries/vmlinux.arm"  \--disk="$IMG_ROOT/disks/m5_exit.squashfs.arm"   \--bootscript=./util/dist/test/simple_bootscript.rcS

脚本分析

下面是对fs_power.py 脚本的解读。

# 导入命令行参数解析模块,用于处理脚本运行时的输入参数
import argparse
# 导入操作系统相关功能模块,用于处理文件路径等系统操作
import os# 导入自定义的 big.LITTLE 架构配置模块(假设为封装了ARM大小核架构的配置逻辑)
import fs_bigLITTLE as bL# 导入gem5的核心模块m5,用于控制仿真流程
import m5
# 从gem5的objects模块导入功耗建模相关的基础类
from m5.objects import (MathExprPowerModel,  # 支持数学表达式的功耗模型基类PowerModel,          # 功耗模型基类
)# 定义CPU在"ON"状态下的功耗模型(继承自支持数学表达式的功耗模型)
class CpuPowerOn(MathExprPowerModel):def __init__(self, cpu_path, **kwargs):# 调用父类构造函数,传递额外参数super().__init__(** kwargs)# 动态功耗计算公式:# 基于CPU的IPC(每周期指令数)和数据缓存缺失率,结合电压计算# 公式含义:电压 × (2×IPC + 3×1e-9×(数据缓存总缺失数/仿真时间))# 注:3×1e-9将缓存缺失的单位转换为与IPC匹配的量级,最终结果单位为瓦特self.dyn = ("voltage * (2 * {}.ipc + 3 * 0.000000001 * ""{}.dcache.overallMisses / simSeconds)".format(cpu_path, cpu_path))# 静态功耗计算公式:与温度成正比(4×温度)self.st = "4 * temp"# 定义CPU在非"ON"状态(如关闭、时钟门控)的功耗模型
class CpuPowerOff(MathExprPowerModel):# 动态功耗为0(无开关活动)dyn = "0"# 静态功耗为0(理想状态下无漏电)st = "0"# 定义CPU的完整功耗模型(管理不同状态下的功耗模型切换)
class CpuPowerModel(PowerModel):def __init__(self, cpu_path, **kwargs):# 调用父类构造函数super().__init__(** kwargs)# 定义功耗状态列表,与gem5的4种功耗状态对应:# [ON, CLK_GATED(时钟门控), SRAM_RETENTION(SRAM保持), OFF(关闭)]self.pm = [CpuPowerOn(cpu_path),  # ON状态使用CpuPowerOn模型CpuPowerOff(),         # 时钟门控状态使用CpuPowerOff模型CpuPowerOff(),         # SRAM保持状态使用CpuPowerOff模型CpuPowerOff(),         # 关闭状态使用CpuPowerOff模型]# 定义L2缓存在"ON"状态下的功耗模型
class L2PowerOn(MathExprPowerModel):def __init__(self, l2_path, **kwargs):super().__init__(** kwargs)# 动态功耗计算公式:基于L2缓存的总访问次数,每次访问贡献0.000018瓦特# 注:0.000018为示例系数,实际需根据缓存大小、工艺参数校准self.dyn = f"{l2_path}.overallAccesses * 0.000018000"# 静态功耗计算公式:与电压相关((电压×3)/10)self.st = "(voltage * 3)/10"# 定义L2缓存在非"ON"状态的功耗模型
class L2PowerOff(MathExprPowerModel):dyn = "0"  # 动态功耗为0st = "0"   # 静态功耗为0# 定义L2缓存的完整功耗模型(管理不同状态下的模型切换)
class L2PowerModel(PowerModel):def __init__(self, l2_path, **kwargs):super().__init__(** kwargs)# 定义L2缓存的功耗状态列表,对应4种状态self.pm = [L2PowerOn(l2_path),   # ON状态使用L2PowerOn模型L2PowerOff(),         # 时钟门控状态使用L2PowerOff模型L2PowerOff(),         # SRAM保持状态使用L2PowerOff模型L2PowerOff(),         # 关闭状态使用L2PowerOff模型]# 主函数:配置仿真环境、绑定功耗模型并启动仿真
def main():# 创建命令行参数解析器,描述脚本功能为"带示例功耗模型的通用ARM big.LITTLE配置"parser = argparse.ArgumentParser(description="Generic ARM big.LITTLE configuration with ""example power models")# 从fs_bigLITTLE模块添加big.LITTLE架构相关的命令行参数(如核数、频率等)bL.addOptions(parser)# 解析命令行参数options = parser.parse_args()# 检查CPU类型是否为"timing",因为功耗模型需要时序仿真支持if options.cpu_type != "timing":# 若不是timing类型,抛出致命错误并终止仿真m5.fatal("The power example script requires 'timing' CPUs.")# 调用fs_bigLITTLE模块的build函数,构建big.LITTLE系统的根对象root = bL.build(options)# 为系统中的所有CPU绑定功耗模型# 遍历系统中所有组件(通过descendants()获取所有子对象)for cpu in root.system.descendants():# 筛选出BaseCPU类型的对象(即CPU核心)if not isinstance(cpu, m5.objects.BaseCPU):continue# 设置CPU的默认功耗状态为"ON"cpu.power_state.default_state = "ON"# 为CPU绑定自定义的功耗模型,传入CPU在系统中的路径(用于引用统计量)cpu.power_model = CpuPowerModel(cpu.path())# 为bigCluster的L2缓存绑定功耗模型# 遍历bigCluster中L2缓存的所有子组件for l2 in root.system.bigCluster.l2.descendants():# 筛选出Cache类型的对象(即L2缓存)if not isinstance(l2, m5.objects.Cache):continue# 设置L2缓存的默认功耗状态为"ON"l2.power_state.default_state = "ON"# 为L2缓存绑定自定义的功耗模型,传入L2在系统中的路径l2.power_model = L2PowerModel(l2.path())# 实例化仿真系统(根据配置创建具体的仿真对象)bL.instantiate(options)# 打印警告信息:说明本脚本的功耗数值仅为示例,不代表实际硬件print("*" * 70)print("WARNING: The power numbers generated by this script are ""examples. They are not representative of any particular ""implementation or process.")print("*" * 70)# 配置统计信息的输出周期:每0.1毫秒(0.1e-3秒)输出一次统计数据m5.stats.periodicStatDump(m5.ticks.fromSeconds(0.1e-3))# 启动仿真运行(调用fs_bigLITTLE模块的run函数)bL.run()# 若脚本作为gem5主程序运行,则调用main函数
if __name__ == "__m5_main__":main()

main函数解析

main 函数是整个脚本的核心执行入口,负责串联 “参数解析、系统构建、功耗模型绑定、仿真启动” 等关键流程,最终实现带功耗建模的 big.LITTLE 架构仿真。其流程可分为 7 个核心部分,各部分的作用和逻辑如下:

1. 参数解析与配置验证

parser = argparse.ArgumentParser(description="...")  # 创建参数解析器
bL.addOptions(parser)  # 添加big.LITTLE架构相关参数(如核数、频率等)
options = parser.parse_args()  # 解析命令行输入参数if options.cpu_type != "timing":  # 验证CPU类型是否符合功耗建模要求m5.fatal("The power example script requires 'timing' CPUs.")

作用

  • 通过 argparse 处理用户输入的命令行参数(如仿真时长、CPU 类型等),确保参数符合脚本运行要求。

  • 关键验证:强制要求 CPU 类型为 timing(时序模型),因为功耗模型依赖时序仿真的统计数据(如 IPC、缓存访问等)。

2. 构建 big.LITTLE 系统架构

root = bL.build(options)  # 调用自定义模块构建系统根对象

作用

  • 基于解析后的参数(options),通过 fs_bigLITTLE 模块的 build 函数创建 big.LITTLE 架构的系统根对象(root)。

  • 系统根对象包含仿真所需的全部硬件组件(如 big 核集群、LITTLE 核集群、缓存、内存、总线等),是后续配置的基础。

3. 为 CPU 绑定功耗模型

for cpu in root.system.descendants():  # 遍历系统中所有组件if not isinstance(cpu, m5.objects.BaseCPU):  # 筛选出CPU核心continuecpu.power_state.default_state = "ON"  # 设置默认功耗状态为"运行中"cpu.power_model = CpuPowerModel(cpu.path())  # 绑定自定义的CPU功耗模型

作用

  • 遍历系统中的所有组件,筛选出 CPU 核心(BaseCPU 类型)。

  • 为每个 CPU 配置默认功耗状态(ON),并绑定之前定义的 CpuPowerModel(包含不同状态下的功耗计算公式),使 CPU 的运行数据(如 IPC、缓存缺失)能被功耗模型引用。

4. 为 L2 缓存绑定功耗模型

for l2 in root.system.bigCluster.l2.descendants():  # 遍历big集群的L2缓存组件if not isinstance(l2, m5.objects.Cache):  # 筛选出缓存组件continuel2.power_state.default_state = "ON"  # 设置默认功耗状态为"运行中"l2.power_model = L2PowerModel(l2.path())  # 绑定自定义的L2功耗模型

作用

  • 针对 big 核集群的 L2 缓存,筛选出缓存组件(Cache 类型)。

  • 配置默认功耗状态(ON),并绑定 L2PowerModel,使 L2 缓存的访问数据(如 overallAccesses)能用于计算缓存的动态 / 静态功耗。

5. 实例化仿真系统

bL.instantiate(options)  # 实例化仿真对象

作用

  • 将之前定义的系统架构(root)、功耗模型等配置 “实例化” 为 gem5 可执行的仿真对象。

  • 这一步会完成硬件组件的底层映射(如内存地址分配、总线连接等),是从 “配置描述” 到 “可运行仿真” 的关键转换。

6. 输出警告信息

print("*" * 70)
print("WARNING: The power numbers generated by this script are examples...")
print("*" * 70)

作用

  • 提示用户当前脚本的功耗数据是示例值(系数如 23 未经过实际硬件校准),不代表真实芯片的功耗特性,避免误用仿真结果。

7. 配置统计输出与启动仿真

m5.stats.periodicStatDump(m5.ticks.fromSeconds(0.1e-3))  # 每0.1毫秒输出一次统计数据
bL.run()  # 启动仿真

作用

  • 配置统计信息的输出周期(每 0.1 毫秒一次),确保能实时记录功耗、性能等关键指标(如动态功耗、IPC、缓存缺失率等)。

  • 调用 bL.run() 启动仿真流程,执行预设的工作负载(如应用程序、基准测试等),并在仿真过程中根据功耗模型实时计算功耗。

总结:main 函数的核心逻辑

main 函数通过 “参数解析→系统构建→功耗模型绑定→实例化→启动仿真” 的流程,将 “big.LITTLE 硬件架构” 与 “自定义功耗模型” 结合,最终实现带功耗统计的仿真。其核心价值是将抽象的功耗计算公式与具体的硬件组件关联,并通过 gem5 的仿真引擎输出量化的功耗数据,为芯片功耗优化提供参考。


文章转载自:

http://f5L9moYe.yrkdq.cn
http://icCpL8Oj.yrkdq.cn
http://vjesF2Fg.yrkdq.cn
http://Kxih7UNg.yrkdq.cn
http://MQuV1Jfq.yrkdq.cn
http://IxTtym2b.yrkdq.cn
http://dUA1NRDB.yrkdq.cn
http://L6tIlNfj.yrkdq.cn
http://5qR9Bjz0.yrkdq.cn
http://uWR6fcaQ.yrkdq.cn
http://FBg4KNnm.yrkdq.cn
http://dEKvu0nc.yrkdq.cn
http://YK0a55th.yrkdq.cn
http://ShaO8IfP.yrkdq.cn
http://Vx4lsrBi.yrkdq.cn
http://g3SheTmQ.yrkdq.cn
http://HnRRM3hl.yrkdq.cn
http://qfnKu9rB.yrkdq.cn
http://JX8WsF5m.yrkdq.cn
http://WnLv6S4I.yrkdq.cn
http://kJMsb1pk.yrkdq.cn
http://dpvC9gx1.yrkdq.cn
http://wrBQEcye.yrkdq.cn
http://nLFSo2WE.yrkdq.cn
http://W2RPDV0B.yrkdq.cn
http://nizxRWR4.yrkdq.cn
http://A9jlj5xR.yrkdq.cn
http://7o72Xx5A.yrkdq.cn
http://NUXURwBr.yrkdq.cn
http://MZvhPKXM.yrkdq.cn
http://www.dtcms.com/a/373869.html

相关文章:

  • TCP 拥塞控制与四次挥手解析
  • Linux 进程深度解析:从底层架构到虚拟地址空间
  • 软件测试之测试分类(沉淀中)
  • 使用Postfix+Dovecot+数据库+Web界面搭建邮件服务器详细指南
  • ubuntu 安装 docker 详细步骤
  • 无外部依赖!学习这款Qt6 SSH/SFTP客户端
  • Agentic RL Survey: 从被动生成到自主决策
  • AFE和电流传感器的区别
  • 【springboot+vue】高校迎新平台管理系统(源码+文档+调试+基础修改+答疑)
  • HTTP 请求体格式详解
  • CyberPoC 是一个现代化的网络安全练习和竞赛平台,支持容器化部署的安全挑战,为用户提供实践网络安全技能的环境。
  • Mybatis Log Plugin打印日志,会导致CPU升高卡死
  • 并发编程原理与实战(二十七)深入剖析synchronized底层基石ObjectMonitor与对象头Mark Word
  • 国产化Word处理组件Spire.DOC教程:使用 Python 将 Markdown 转换为 HTML 的详细教程
  • CanMV K230 2025年度计划
  • 简单视频转换器 avi转mp4
  • 如何修改不同城市IP查询排名以增强广告投放效果
  • 04-Redis 启动与停止:服务管理全攻略(含命令行与图形化操作)
  • LangChain: Agent(代理)
  • 使用 BatchRendererGroup 创建渲染器
  • flutter鸿蒙:使用flutter_local_notifications实现本地通知
  • Redis中数据类型详解
  • CentOS 7安装最新nginx
  • 解决Win11 安全中心删掉存在隐患的工具
  • 二级缓存在实际项目中的应用
  • 第14篇:循环神经网络(RNN)与LSTM:序列建模的利器
  • 【P02_AI大模型之调用LLM的方式】
  • 浅谈Go 语言开发 AI Agent
  • pgsql for循环一个 数据文本 修改数据 文本如下 ‘40210178‘, ‘40210175‘, ‘40210227‘, ‘40210204‘
  • 工业检测机器视觉为啥非用工业相机?普通相机差在哪?