利用 Gem5 模拟器创建一个简单的配置脚本——翻译自官网

news2024/10/5 12:42:28

文章目录

      • 创建简单的配置脚本
        • gem5 配置脚本
          • 关于模拟对象的插话
        • 创建配置文件
          • 全系统与系统调用模拟
        • 运行Gem5

在这里插入图片描述

创建简单的配置脚本

本章教程将指导你如何为 gem5 设置一个简单的模拟脚本,并首次运行 gem5。我们假定你已完成本教程第一章的学习,并已成功创建 gem5 的可执行文件 build/X86/gem5.opt。

我们的配置脚本将模拟一个非常简单的系统。我们只有一个简单的 CPU 内核。这个 CPU 内核将连接到整个系统的内存总线上。我们将有一个 DDR3 内存通道,也连接到内存总线上。

gem5 配置脚本

gem5 二进制文件的参数是一个用于设置和执行模拟的 python 脚本。在这个脚本中,你需要创建一个要模拟的系统,创建系统的所有组件,并指定系统组件的所有参数。然后,您就可以从脚本中开始模拟。

该脚本完全由用户定义。您可以选择在配置脚本中使用任何有效的 Python 代码。本书提供了一个在很大程度上依赖 Python 中类和继承的风格示例。作为 gem5 用户,您可以自行决定让您的配置脚本变得多么简单或复杂。

在 configs/examples 中,gem5 提供了大量示例配置脚本。这些脚本大多包罗万象,允许用户在命令行中指定几乎所有选项。在本书中,我们将不从这些复杂的脚本开始,而是从能够运行 gem5 的最简单脚本开始,并以此为基础进行构建。希望在本节结束时,你能对模拟脚本的工作原理有所了解。

关于模拟对象的插话

gem5 的模块化设计围绕 SimObject 类型展开。模拟系统中的大部分组件都是 SimObjects: gem5将所有这些对象从其C++实现导出到python。因此,通过 python 配置脚本,你可以创建任何 SimObject、设置其参数并指定 SimObject 之间的交互。

更多信息,请参阅 SimObject 详情。

创建配置文件

让我们先创建一个新的配置文件并打开它:

mkdir configs/tutorial/part1/
touch configs/tutorial/part1/simple.py

这只是一个普通的 python 文件,将由 gem5 可执行文件中的嵌入式 python 执行。因此,你可以使用 python 中的任何功能和库。
在该文件中,我们要做的第一件事就是导入 m5 库和所有已编译的模拟对象。

import m5
from m5.objects import *

接下来,我们将创建第一个 SimObject:我们要模拟的系统。系统对象将是模拟系统中所有其他对象的父对象。系统对象包含大量功能(非时序级)信息,如物理内存范围、根时钟域、根电压域、内核(在全系统仿真中)等。要创建系统 SimObject,我们只需像普通 Python 类一样将其实例化:

system = System()

现在我们有了要模拟的系统的参考,让我们来设置系统的时钟。我们首先要创建一个时钟域。然后,我们可以在该域上设置时钟频率。在 SimObject 上设置参数与在 python 中设置对象成员完全相同,因此我们可以简单地将时钟频率设置为 1 GHz。最后,我们必须为该时钟域指定一个电压域。由于我们现在并不关心系统功耗,因此只需使用电压域的默认选项即可。

system.clk_domain = SrcClockDomain()
system.clk_domain.clock = ‘1GHz’
system.clk_domain.voltage_domain = VoltageDomain()

有了系统后,让我们来设置如何模拟内存。我们将使用定时模式进行内存模拟。除了快进和从检查点恢复等特殊情况外,内存模拟几乎总是使用定时模式。我们还将设置一个 512 MB 大小的单一内存范围,这是一个非常小的系统。请注意,在 python 配置脚本中,只要需要指定内存大小,就可以用 "512MB "这样的普通话和单位来指定。同样,对于时间,您也可以使用时间单位(如 “5ns”)。这些单位将分别自动转换为通用表示法。

system.mem_mode = ‘timing’
system.mem_ranges = [AddrRange(‘512MB’)]

现在,我们可以创建一个 CPU。我们将从 gem5 中最简单的基于 X86 ISA 的定时 CPU X86TimingSimpleCPU 开始。该 CPU 模型在一个时钟周期内执行每条指令,但内存请求除外,内存请求流经内存系统。要创建 CPU,只需实例化该对象即可:

system.cpu = X86TimingSimpleCPU()

如果我们想使用 RISCV ISA,可以使用 RiscvTimingSimpleCPU;如果我们想使用 ARM ISA,可以使用 ArmTimingSimpleCPU。不过,在本练习中我们将继续使用 X86 ISA。
接下来,我们将创建全系统内存总线:

system.membus = SystemXBar()

既然有了内存总线,我们就将 CPU 上的高速缓存端口连接到内存总线上。在本例中,由于我们要模拟的系统没有任何缓存,我们将把 I 缓存和 D 缓存端口直接连接到内存总线上。在本示例系统中,我们没有缓存。

system.cpu.icache_port = system.membus.cpu_side_ports
system.cpu.dcache_port = system.membus.cpu_side_ports

  • 关于 gem5 端口的插话
    为了将内存系统组件连接在一起,gem5 使用了端口抽象。每个内存对象可以有两种端口,即请求端口和响应端口。请求从请求端口发送到响应端口,响应从响应端口发送到请求端口。连接端口时,必须将请求端口连接到响应端口。

通过 python 配置文件很容易将端口连接在一起。只需设置请求端口 = 响应端口,它们就会连接在一起。例如

system.cpu.icache_port = system.l1_cache.cpu_side

在本例中,cpu 的 icache_port 是请求端口,缓存的 cpu_side 是响应端口。请求端口和响应端口可以位于 = 的任何一侧,并将建立相同的连接。建立连接后,请求者就可以向响应者发送请求。建立连接的幕后工作非常复杂,对大多数用户来说,其中的细节并不重要。

在 gem5 Python 配置中,另一个值得注意的神奇之处是,可以在一侧使用一个端口,而在另一侧使用端口数组。例如

system.cpu.icache_port = system.membus.cpu_side_ports

在本例中,cpu 的 icache_port 是一个请求端口,而 membus 的 cpu_side_ports 是一个响应端口数组。在这种情况下,cpu_side_ports 上会产生一个新的响应端口,这个新创建的端口将连接到请求端口。

我们将在 MemObject 章节详细讨论端口和 MemObject。

接下来,我们需要连接其他几个端口,以确保系统正常运行。我们需要在 CPU 上创建一个 I/O 控制器,并将其连接到内存总线。此外,我们还需要将系统中的一个特殊端口连接到内存总线上。该端口为功能专用端口,允许系统读写内存。

将 PIO 和中断端口连接到内存总线是 x86 的特定要求。其他 ISA(如 ARM)不需要这 3 条额外的线路。

system.cpu.createInterruptController()
system.cpu.interrupts[0].pio = system.membus.mem_side_ports
system.cpu.interrupts[0].int_requestor = system.membus.cpu_side_ports
system.cpu.interrupts[0].int_responder = system.membus.mem_side_ports

system.system_port = system.membus.cpu_side_ports

接下来,我们需要创建一个内存控制器,并将其连接到内存总线。在本系统中,我们将使用一个简单的 DDR3 控制器,它将负责整个系统的内存范围。

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

完成这些最后的连接后,我们就完成了模拟系统的实例化!我们的系统应该如下图所示。
在这里插入图片描述
接下来,我们需要设置希望 CPU 执行的进程。由于我们是在系统调用模拟模式(SE 模式)下执行,因此只需将 CPU 指向编译后的可执行文件即可。我们将执行一个简单的 "Hello world "程序。gem5 中已经有一个编译好的程序,我们就用它。你可以指定任何为 x86 构建并经过静态编译的应用程序。

全系统与系统调用模拟

gem5 可在两种不同的模式下运行,即 "系统调用模拟 "和 "全系统 "模式,或称 SE 和 FS 模式。在全系统模式(稍后将介绍全系统部分)下,gem5 会模拟整个硬件系统,并运行未经修改的内核。全系统模式类似于运行虚拟机。

另一方面,系统调用仿真模式并不仿真系统中的所有设备,而是专注于模拟 CPU 和内存系统。由于不需要实例化真实系统中所需的所有硬件设备,因此系统调用仿真更易于配置。不过,系统调用仿真只能仿真 Linux 系统调用,因此只能模拟用户模式代码。

如果研究问题时不需要对操作系统进行建模,又希望获得更高的性能,则应使用 SE 模式。但是,如果你需要高保真的系统建模,或者操作系统交互(如页表走行)很重要,那么你就应该使用 FS 模式。

首先,我们必须创建进程(另一个模拟对象)。然后将进程命令设置为要运行的命令。这是一个类似 argv 的列表,第一个位置是可执行文件,其余位置是可执行文件的参数。然后我们将 CPU 设置为使用进程作为其工作负载,最后在 CPU 中创建功能执行上下文。

binary = ‘tests/test-progs/hello/bin/x86/linux/hello’
#for gem5 V21 and beyond(#后面应该要有一个空格)
system.workload = SEWorkload.init_compatible(binary)
process = Process()
process.cmd = [binary]
system.cpu.workload = process
system.cpu.createThreads()

我们需要做的最后一件事就是实例化系统并开始执行。首先,我们创建根对象。然后实例化模拟。实例化过程将遍历我们在 python 中创建的所有 SimObjects,并创建对应的 C++ 对象。
需要注意的是,您不必先实例化 python 类,然后再将参数明确指定为成员变量。您也可以将参数作为命名参数传递,例如下面的根对象。

root = Root(full_system = False, system = system)
m5.instantiate()

最后,我们就可以开始实际模拟了!另外,gem5 现在使用 Python 3 风格的 print 函数,因此 print 不再是语句,而必须作为函数调用。

print(“Beginning simulation!”)
exit_event = m5.simulate()

模拟完成后,我们就可以检查系统的状态。

print(‘Exiting @ tick {} because {}’
.format(m5.curTick(), exit_event.getCause()))

运行Gem5

现在,我们已经创建了一个简单的模拟脚本(其完整版本可在gem5代码库中的configs/learning_gem5/part1/simple.py找到),我们已经准备好运行gem5了。gem5可以接受许多参数,但只需要一个位置参数,即模拟脚本。因此,我们只需在 gem5 根目录下运行 gem5 即可:

build/X86/gem5.opt configs/tutorial/part1/simple.py

输出结果应为
在这里插入图片描述
可以更改配置文件中的参数,但结果应有所不同。例如,如果将系统时钟提高一倍,模拟完成的速度应该会更快。或者,如果将 DDR 控制器更改为 DDR4,性能应该会更好。

此外,您还可以将 CPU 模型更改为 X86MinorCPU 以模拟顺序内 CPU,或 X86O3CPU 以模拟顺序外 CPU。但请注意,X86O3CPU 目前不能与 simple.py 一起使用,因为 X86O3CPU 要求系统具有独立的指令缓存和数据缓存(X86O3CPU 可与下一节中的配置一起使用)。

所有 gem5 BaseCPU 的命名格式都是 {ISA}{Type}CPU。因此,如果我们要使用 RISCV MinorCPU,就必须使用 RiscvMinorCPU。

有效的 ISA 有

  • Riscv
  • Arm
  • X86
  • Sparc
  • Power
  • Mips

CPU 类型有

  • 原子简单 CPU(AtomicSimpleCPU)
  • O3CPU(O3CPU)
  • 定时简单CPU(TimingSimpleCPU)
  • KvmCPU(KvmCPU)
  • 次要 CPU(MinorCPU)
    接下来,我们将在配置文件中添加缓存,以模拟更复杂的系统。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1233765.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DITTEL控制器维修SENSITRON6-2AE

DITTEL工控产品维修包括:德国DITTEL平衡测试仪维修,DITTEL模块,过程监控模块,DITTEL控制器,平衡头,机电平衡头,显示器,平衡系统等产品。 DITTEL过程控制模块维修 DM6000是一个过程控制模块&…

第1关:图的邻接表存储及求邻接点操作

任务要求参考答案评论2 任务描述相关知识编程要求测试说明 任务描述 本关任务:要求从文件输入顶点和边数据,包括顶点信息、边、权值等,编写程序实现以下功能。 1)构造图G的邻接表和顶点集,即图的存储结构为邻接表。 …

使用wxPython和PyMuPDF合并PDF文档并自动复制到剪贴板

导语:处理大量的PDF文档可能会变得复杂和耗时。但是,使用Python编程和一些强大的库,如wxPython和PyMuPDF,可以使这个任务变得简单而高效。本文将详细解释一个示例代码,展示如何使用这些库来创建一个可以选择文件夹中的…

STM32 -Bin/Hex文件格式解析

文章目录 1. 概述2. Hex文件2.1 格式解析2.2 数据类型2.3 举例解析2.4 合并两个Hex文件方法 3 总结(未完待续) 1. 概述 Hex文件:它是单片机和嵌入式工程编译输出的一种常见的目标文件格式(比如keil就能编译输出hex文件&#xff0…

Kubernetes容器状态探测的艺术

在Kubernetes集群中维护容器状态更像是一种艺术,而不是科学。原文: The Art and Science of Probing a Kubernetes Container[1] 在Kubernetes集群中维护容器状态更像是一种艺术,而不是科学。 本文将带你深入理解容器探测[2],并特别关注相对较…

SQL常见函数整理 —— LAG() 向上偏移

1. 用法 窗口函数,用于访问窗口中当前行之前的行的数据。该函数可以根据需要计算当前行之前的值,使我们能够轻松地比较不同行之间的差异和变化。 2. 基本语法 LAG(column, offset, default_value) OVER (ORDER BY column)column:代表在返回…

代码随想录刷题】Day15 二叉树02------延伸题目练习

文章目录 1.【100】相同的树1.1 题目描述1.2 java代码实现 2.【572】另一棵树的子树2.1 题目描述2.2 java代码实现 【100】相同的树 【572】另一棵树的子树 1.【100】相同的树 1.1 题目描述 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。…

“轻松管理你的文件库:按大小归类保存,高效整理!“

亲爱的朋友们,你是否曾经为了整理电脑中杂乱无章的文件而感到烦恼?文件大小不一,无法快速找到所需内容,实在让人感到心力交瘁。但现在,我们为你带来一种全新的解决方案,让你的文件管理更轻松,更…

算法设计与分析复习--回溯(一)

文章目录 上一篇回溯法性质子集和问题装载问题0-1背包问题下一篇 上一篇 算法设计与分析复习–贪心(二) 回溯法性质 类似穷举的搜索尝试过程,在搜索尝试过程中寻找问题的解,组织得井井有条(避免遗漏)&am…

工业领域的设备“监测”和“检测”有何区别?

在工业领域中,设备的监测和检测是关键的运维活动,它们在保障设备可靠性和生产效率方面发挥着重要作用。尽管这两个术语经常被人们混为一谈,但它们在含义和应用上存在一些关键区别。 "监测"与"检测"的概念 1. 监测&#…

PHP手动为第三方类添加composer自动加载

有时候我们要使用的第三方的类库(SDK)没用用composer封装好,无法用composer进行安装,怎么办呢??? 步骤如下: 第一步、下载你需要的SDK文件包,把它放在vendor目录下 第二…

【Python】学习Python面向对象编程的疑问

(Java菜鸟来学Python了) 🤔 1. 静态方法与类方法什么区别? 实例方法只能被实例对象调用(Python3 中,如果类调用实例方法,需要显示的传self, 也就是实例对象自己),静态方法(由staticmethod装饰…

【MATLAB源码-第84期】基于matlab的802.11a标准的OFDM系统误码仿真对比QPSK,16QAM。

操作环境: MATLAB 2022a 1、算法描述 基于802.11a标准的OFDM(正交频分复用)系统是一种高效的无线通信技术,特点如下: 频带与信道: 802.11a工作在5 GHz频段,这个频段相对于2.4 GHz&#xff08…

O-Star|再相识

暑去秋来,岁月如梭,几名"O-Star"们已经入职一段时间,在这期间他们褪去青涩,逐渐适应了公司的工作环境和文化,迈向沉稳~ 为了进一步加深校招生之间的交流与了解,提高校招生的凝聚力和…

77基于matlab的蚁群优化路径算法,二维路径和三维路径优化

基于matlab的蚁群优化路径算法,二维路径和三维路径优化。输出可视化最优路径和距离迭代曲线。数据可更换自己的,程序已调通,可直接运行。 77三维和二维路径可视化 (xiaohongshu.com)

Docker快速安装Mariadb11.1

MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。在存储引擎方面,使用XtraDB来代替MySQL的InnoDB。 Mari…

第2关:图的深度优先遍历

任务要求参考答案评论2 任务描述相关知识编程要求测试说明 任务描述 本关任务:以邻接矩阵存储图,要求编写程序实现图的深度优先遍历。 相关知识 图的深度优先遍历类似于树的先序遍历, 是树的先序遍历的推广,其基本思想如下: …

如何利用CHATGPT写主题文章

问CHAT:新课标下畅言智慧课堂助力小学生量感培养,拟解决的关键问题 CHAT回复: 1. 确定智慧课堂在新课标下的正确应用方法:新课标对教育方法、内容等提出了新的要求,需要探讨如何将智慧课堂与新课标相结合,…

Rockchip Clock

一:概述 1、时钟子系统 本章节所指的时钟是给SOC各个组件提供时钟的树状框架,而非内核使用的时钟。和其他模块一样,CLOCK也有框架,用以适配不同的平台。适配层之上是客户代码和接口,也就是各模块(如需要时钟信号的外设)的驱动。适配层之下是具体的SOC的时钟操作细节。…