gem5模拟器入门(二)——创建一个简单的配置脚本

        本章教程将引导您设置一个简单的 gem5 仿真脚本,并首次运行 gem5。假设您已经完成了gem5模拟器入门(一)——环境配置-CSDN博客,并成功构建了带有可执行文件 build/X86/gem5.opt 的 gem5。

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

gem5 配置脚本

        gem5 二进制文件接受一个 Python 脚本作为参数,该脚本设置并执行仿真。在这个脚本中,您将创建一个要模拟的系统,创建系统的所有组件,并指定系统组件的所有参数。然后,您可以从脚本中开始仿真。

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

        在 gem5 中的 configs/examples 目录中,有许多示例配置脚本。这些脚本大多数都是包罗万象的,允许用户在命令行上指定几乎所有选项。与其从这些复杂的脚本开始,本书将从一个可以运行 gem5 的最简单脚本开始,然后逐步构建。希望到本节结束时,您会对仿真脚本的工作原理有一个很好的了解。

SimObjects

gem5 的模块化设计是围绕 SimObject 类型构建的。模拟系统中的大多数组件都是 SimObjects:CPU、缓存、内存控制器、总线等。gem5 将所有这些对象从其 C++ 实现导出到 Python。因此,从 Python 配置脚本中,您可以创建任何 SimObject,设置其参数,并指定 SimObjects 之间的交互。

1.创建配置文件

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

这只是一个普通的 Python 文件,将由 gem5 可执行文件中的嵌入式 Python 执行。因此,您可以使用 Python 中的任何功能和库。

在这个文件中我们要做的第一件事是导入 m5 库和我们编译的所有 SimObjects。

import m5
from m5.objects import *

接下来,我们将创建第一个 SimObject:我们要模拟的系统。System 对象将是我们模拟系统中所有其他对象的父对象。System 对象包含了许多功能性(非时序级)信息,比如物理内存范围、根时钟域、根电压域、内核(在全系统仿真中)等。要创建系统 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-cache和D-cache端口连接到内存总线上。在这个示例系统中,我们没有缓存。

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上生成一个新的响应端口,并且这个新创建的端口将连接到请求端口。

接下来,我们需要连接一些其他的端口,以确保我们的系统能够正常运行。我们需要在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_portssystem.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构建且已静态编译的应用程序。

 Full system vs syscall emulation

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

另一方面,系统调用模拟模式并没有模拟系统中的所有设备,而是专注于模拟CPU和内存系统。系统调用模拟配置要简单得多,因为您不需要实例化实际系统中需要的所有硬件设备。然而,系统调用模拟只模拟Linux系统调用,因此只模拟用户模式代码。

如果您的研究问题不需要模拟操作系统,并且需要额外的性能,那么您应该使用SE模式。然而,如果您需要对系统进行高保真建模,或者像页表遍历这样的操作系统交互很重要,那么您应该使用FS模式。

首先,我们必须创建进程(另一个SimObject)。然后,我们将进程的命令设置为我们要运行的命令。这是一个类似于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()

我们需要做的最后一件事是实例化系统并开始执行。首先,我们创建Root对象。然后,我们实例化模拟。实例化过程会遍历我们在Python中创建的所有SimObjects,并创建它们的C++等效对象。

需要注意的是,您不必实例化Python类,然后将参数显式地指定为成员变量。您还可以将参数作为命名参数传递,就像下面的Root对象一样。

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

最后,我们可以启动实际的模拟了!顺便说一下,gem5现在使用Python 3风格的打印函数,因此print不再是一个语句,而必须作为一个函数调用。

print("Beginning simulation!")
exit_event = m5.simulate()

一旦模拟结束,我们就可以检查系统的状态。

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

2.运行gem5

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

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

输出如下:

gem5 Simulator System.  https://www.gem5.org
gem5 is copyrighted software; use the --copyright option for details.gem5 version 23.1.0.0
gem5 compiled May 28 2024 11:47:30
gem5 started May 28 2024 13:06:09
gem5 executing on Aquarius, pid 168573
command line: build/X86/gem5.opt configs/learning_gem5/part1/simple.pyGlobal frequency set at 1000000000000 ticks per second
warn: No dot file generated. Please install pydot to generate the dot file and pdf.
src/mem/dram_interface.cc:692: warn: DRAM device capacity (8192 Mbytes) does not match the address range assigned (512 Mbytes)
src/base/statistics.hh:279: warn: One of the stats is a legacy stat. Legacy stat is a stat that does not belong to any statistics::Group. Legacy stat is deprecated.
system.remote_gdb: Listening for connections on port 7000
Beginning simulation!
src/sim/simulate.cc:199: info: Entering event queue @ 0.  Starting simulation...
Hello world!
Exiting @ tick 503912000 because exiting with last active thread context

在配置文件中更改参数应该会产生不同的结果。例如,如果你将系统时钟加倍,模拟应该会更快完成。或者,如果你将DDR控制器改为DDR4,性能应该会更好。

此外,您还可以将CPU模型更改为X86MinorCPU以模拟顺序CPU,或者将其更改为X86O3CPU以模拟乱序CPU。然而,请注意,X86O3CPU当前无法与simple.py一起使用,因为X86O3CPU需要具有单独的指令和数据缓存的系统(X86O3CPU可以与下一节中的配置一起使用)。

所有gem5的BaseCPU都采用格式{ISA}{Type}CPU的命名格式。因此,如果我们想要一个RISCV Minor CPU,我们将使用RiscvMinorCPU。

有效的ISA有:

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

CPU类型有:

  • AtomicSimpleCPU
  • O3CPU
  • TimingSimpleCPu
  • KvmCPU
  • MinorCPU

接下来,我们将在配置文件中添加缓存,以模拟一个更复杂的系统。

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

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

相关文章

在PYTHON程序中利用FFmpeg录屏真的很好用

FFmpeg是一个开源的跨平台音视频处理工具,拥有强大的音视频编解码能力和丰富的处理功能。它支持包括视频、音频在内的多媒体数据的转换、编辑、播放等操作,被广泛应用于音视频领域的编解码、转码、流媒体处理等方面。 以下是FFmpeg的一些主要特点和功能…

LangChain实战 | 3分钟学会SequentialChain怎么传多个参数

SequentialChain参数传递,总结了以下四种类型 参数传递入参出参一 对 一11一 对 多1n多 对 一n1多 对 多nn 0.连接大模型 先选一个llm,参考这篇博客选择一个国内大模型 LangChain连接国内大模型测试|智谱ai、讯飞星火、通义千问 from langchain_comm…

网络侦察技术

网络侦察技术 收集的信息网络侦察步骤搜索引擎检索命令bing搜索引擎Baidu搜索引擎Shodan钟馗之眼(zoomeye) whois数据库:信息宝库查询注册资料 域名系统网络拓扑社交网络跨域拓展攻击 其它侦察手段社会工程学社会工程学常见形式Web网站查询 其它非技术侦察手段总结网…

巅峰对决:OpenAI与Google如何用大模型开创未来

2024年,人工智能领域正引领着一场波澜壮阔的全球技术革命。 5月14日,OpenAI揭开了其新一代多模态人工智能大模型GPT4系列的神秘面纱,其中GPT-4o不仅拥有流畅迷人的嗓音,还展现出幽默、机智和深刻的洞察力……紧接着,在…

linux下cp和mv命令显示进度条

1.查看当前系统下coreutils工具包的版本号: [rootk8s-master ~]# rpm -qa | grep -w coreutils coreutils-8.22-24.el7_9.2.x86_64当前版本为8.22。 因为cp 和 mv 命令由 coreutils 软件包提供,所以需要重新下载 coreutils 软件包配置补丁 2.下载core…

数据结构——顺序表基本操作的实现(初始化、取值、查找、插入)

一、线性表与顺序表的概述 线性表的数据元素的逻辑特征是线性的,是一种典型的线性结构。这样的结构可以借鉴数组,如数组a[10]中,a[1]前一定是a[0],a[1]后一定是a[2],首结点(a[0])前面无元素&am…

java医院管理系统源码(springboot+vue+mysql)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的医院管理系统。项目源码以及部署相关请联系风歌,文末附上联系信息 。 项目简介: 医院管理系统的主要使用者分…

VR法治教育展厅互动体验突破了地域限制

VR全景互动展厅搭建编辑器以其卓越的特点、强大的功能及实际应用中的显著优势,成为企业级VR应用的得力助手。这款软件不仅能够制作逼真的虚拟场景,更能让用户沉浸其中,体验前所未有的真实感。 它拥有高度逼真的视觉效果,采用先进的…

智能单款计划助力品牌利润增长

零售品牌若要在激烈的市场竞争中胜出,季中单款的管理无疑是商品生命周期管理的核心环节之一。而单款计划的制定,首先依赖于对爆款、平销及滞销产品的敏锐洞察。一个利润现象不得不引起我们的关注:爆款产品的销售,往往成为拉动品牌…

svix - webhooks

文章目录 一、关于 SvixClient Library Overview与 Svix 托管服务的区别 二、运行服务器1、部署1.1 Docker1) 使用 Docker Compose2) 独立容器 1.2 预编译的二进制文件1.3 从源代码构建 2、运行时依赖项3、Redis/Valkey 注意事项持久性 Eviction 政策4、服务器配置4.1 配置文件…

express.js--生成token(二)

主要作用是访问路由接口时,生成身份权限信息 下载依赖 npm i express-jwt npm i jsonwebtoken 配置管理 config/index.js module.exports {app: {port: process.PORT || 3000,//jwt密钥jwtSecret: jwtSecret,//token过期时间expiresIn: 60 * 60 * 24,} } con…

从零开始:如何集成美颜SDK和优化美颜接口

今天,小编将从零开始,详细讲解如何集成SDK并优化美颜接口。 一、选择合适的美颜SDK 评估SDK的功能 在评估过程中,可以通过阅读官方文档、查看示例代码以及实际测试来确定SDK是否符合需求。 兼容性和性能 确保其支持你开发的应用平台&…

【代码随想录算法训练营第37期 第二十一天 | LeetCode530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先】

代码随想录算法训练营第37期 第二十一天 | LeetCode530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先 一、530.二叉搜索树的最小绝对差 解题代码C: /*** Definition for a binary tree node.* struct TreeNode {* int val;* …

【网络】高级IO(select||poll||epoll)

基础引入 应用层read&&write的时候,把数据从用户层写到操作系统,本质是拷贝函数。read时候如果缓冲区没有数据,那么就要等待数据才能读取,因此IO等待拷贝,要进行拷贝,必须等待读写事件就绪。高效I…

成长之路Flutter中的TextField组件

TextField组件本身具备多种属性,支持很多参数设置来实现不同样式效果。 TextField组件可直接上手使用,但默认样式和输入规则并不一定是需求开发中想要的(实话说默认样式并不好看)。下面就通过Flutter TextField组件属性介绍来自定…

Android15 Beta更新速览

Android15 Beta更新速览 前台服务变更 前台服务使应用保持活动状态,以便它们可以执行关键且对用户可见的操作,通常以牺牲电池寿命为代价。在 Android 15 Beta 2 中,dataSync 和 mediaProcessing 前台服务类型现在具有约 6 小时的超时时间&a…

青春旅行家:大学生旅游创业的新星

在青春的岁月里,我们怀揣着梦想,渴望探索世界的每一个角落。对于普通高校的大学生而言,毕业季不仅是人生中的一次重要转折,更是实现梦想、放飞自我的绝佳时机。在这个特殊的时刻,一群年轻的大学生创业者凭借他们的智慧…

内网安全--隧道技术-CS上线本地

免责声明:本文仅做技术交流与学习...请勿非法搞破坏... ---隧道技术:硬刚网络协议,(你不让我走我偏走!) 解决不出网协议上线的问题(利用出网协议进行封装出网) 代理协议: SOCKS4/5 代理软件: SocksCap Proxifier ProxyChains(…

YOLOv8改进 | 融合模块 | 用Resblock+CBAM卷积替换Conv【轻量化网络】

💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 在目标检测领域内,尽管YOLO系列的算法傲视群雄,但在某些方面仍然存在改进的空间。在YOLOv8提取特征的时候,由于卷积的缘故,会导致很多信息的丢失。而凯明大神的神作resnet可以减少信息的丢失。本文给大家带…

磁盘管理以及文件系统08

1、为什么要对磁盘进行分区? 业务层面:为满足一定的需求所是做的特定操作。 2、硬盘是什么,以及硬盘的作用 硬盘:计算机的存储设备,一个或者多个带磁性的盘组成的,可以在盘片上进行数据的读写。硬盘的最…