gem5学习——建立X86全系统仿真

目录

关键点

环境

脚本文件详解

0. 导入声明

1. requires模块

2. 处理器配置

3.  工作负载配置

 4. simulator配置

运行过程

1. 执行配置脚本

 2. 使用m5term远程连接

3. 结果

总结


3.14更新

gem5: Memory system进行学习后才知道,Atomic访问和Timing访问不能在一个存储系统中共存,因此在下面介绍的两种CPU切换配置中,两种CPU不能分别是Atomic类型和Timing类型。


 (本文记录对官网教程gem5: X86 Full-System Tutorial的理解和实践)

关键点

  1. 利用gem5中的标准库(standard library)建立了一个双核X86处理器,可以进行全系统模拟(操作Ubuntu操作系统,并运行测试程序)
  2. 该系统可以利用gem5对切换核心的仿真能力(利用一个快速CPU进行操作系统的初始化,然后切换到一个更具体的CPU上进行仿真)
  3. 有助于快速理解gem5全系统建立和仿真过程(kernel、image、启动事件、仿真事件等)
  4. 有助于利用标准库编写系统配置文件

环境

  • ubuntu 18.04
  • gem5 22.0.0.2

脚本文件详解

(源码对应configs/example/gem5_library/x86-ubuntu-run-with-kvm.py,与官方教程略有偏差,但没有关键影响。以下介绍截取源码。)

0. 导入声明

from gem5.utils.requires import requires
from gem5.components.boards.x86_board import X86Board
from gem5.components.memory.single_channel import SingleChannelDDR3_1600
from gem5.components.processors.simple_switchable_processor import (
    SimpleSwitchableProcessor,
)
from gem5.components.processors.cpu_types import CPUTypes
from gem5.isas import ISA
from gem5.coherence_protocol import CoherenceProtocol
from gem5.resources.resource import Resource
from gem5.simulate.simulator import Simulator
from gem5.simulate.exit_event import ExitEvent
from gem5.components.cachehierarchies.ruby.\
    mesi_two_level_cache_hierarchy import (
    MESITwoLevelCacheHierarchy,
)

1. requires模块

requires(
    isa_required=ISA.X86,
    coherence_protocol_required=CoherenceProtocol.MESI_TWO_LEVEL,
    # kvm_required=True,
    kvm_required=False,
)

 require函数的功能是用于检查gem5模拟器(.opt)是否与想要建立的处理器相匹配:

  • ISA
  • 缓存一致性协议
  • KVM

KVM说明

官方教程中需要用到kvm,用于初始化的CPU是基于kvm的,要求主机支持KVM。但我在实际运行时发现我的主机不支持KVM,运行后错误如下:

 尝试配置KVM发现不是很简单,然后了解gem5中的基于KVM的CPU功能为:

gem5支持基于KVM的CPU模型,当主机ISA与gem5中运行的应用程序相同,它能绕过模拟并使用底层主机的处理器来运行gem5中运行的二进制文件,此时gem5上程序的运行速度和在主机上几乎相同。这主要可用于采样模拟以及快速前进到感兴趣区域和检查点位置。

该模型用于加快仿真速度,应该不是必备选项,因此用户可根据实际情况选择性配置

因此我为了避免不必要的问题,选择不使用KVM,在该require函数中将kvm_required参数设置为False,然后在后续设置CPU类型时进行相应的修改。

2. 处理器配置

(1)cache

# Here we setup a MESI Two Level Cache Hierarchy.
cache_hierarchy = MESITwoLevelCacheHierarchy(
    l1d_size="16kB",
    l1d_assoc=8,
    l1i_size="16kB",
    l1i_assoc=8,
    l2_size="256kB",
    l2_assoc=16,
    num_l2_banks=1,
)

(2)memory

# Setup the system memory.
memory = SingleChannelDDR3_1600(size="3GB")

 SingleChannelDDR3_1600模块的默认内存大小为8GiB,但我们所使用的X86Board模块的内存大小最大为3GiB,因此需要在这里设定内存大小参数。

(3)processor

processor = SimpleSwitchableProcessor(
    # starting_core_type=CPUTypes.KVM,
    starting_core_type=CPUTypes.TIMING,

    switch_core_type=CPUTypes.TIMING,
    isa=ISA.X86,
    num_cores=2,
)

在这里使用了gem5标准库中的SimpleSwitchableProcessor类,用于在仿真过程中进行两种类型CPU之间的切换(starting_core_type->switch_core_type) 。官方教程中初始化CPU是基于KVM的CPU,而由于我没有配置KVM,因此在这里将其改为TIMING类型。

注意:在官方教程中提出若不支持KVM,则可以将CPU类型修改为ATOMIC。但我尝试之后发现无法运行,出现以下错误:

 怀疑是ATOMIC不能用于包含Cache的处理器中(真正原因是Atomic类型和Timing类型不能共存),因此将CPU类型修改为TIMING,可正常运行。

(4)board

board = X86Board(
    clk_freq="3GHz",
    processor=processor,
    memory=memory,
    cache_hierarchy=cache_hierarchy,
)

3.  工作负载配置

gem5的全系统模式会启动完整的Linux操作系统,需要配置内核(kernel)和磁盘镜像(disk_image),同时,可选择性配置运行指令列表(readfile_contents),文件内容是启动操作系统后在由于仿真的指令序列。

command = "m5 exit;" \
        + "echo 'This is running on Timing CPU cores.';" \
        + "sleep 1;" \
        + "m5 exit;"

board.set_kernel_disk_workload(
    # The x86 linux kernel will be automatically downloaded to the if not
    # already present.
    kernel=Resource("x86-linux-kernel-5.4.49"),
    # The x86 ubuntu image will be automatically downloaded to the if not
    # already present.
    disk_image=Resource("x86-ubuntu-18.04-img"),
    readfile_contents=command,
)

(1)kernel & disk_image

官方教程中使用的kernel和disk_image直接来自于gem5资源库(resource repository),直接利用Resource类(应该是直接下载到本地)。用户也可以使用自定义的kernel和disk_image。

问题:这个kernel和disk_image除了指定操作系统以外,还有什么影响吗?会影响到仿真处理器的配置上限吗?如果与处理器配置无关的话,那为什么还需要自定义 呢?

注意:这里选用的磁盘镜像文件是x86-ubuntu18.04-img,它被设计为启动操作系统、自动登陆并执行m5 readfile。m5 readfile内容通过readfile_contents指定,因此若所用该镜像文件,需指定参数readfile_contents,不然在成功进入操作系统后将直接退出,不能通过终端执行指令。(这也就是为什么运行脚本文件x86-ubuntu-run.py时,使用终端接入该操作系统后会直接退出。下图展示该过程。)

 (2)指令序列文件

文件内容为command的值,传给readfile_contents参数,最终将存储在文件gem5/m5out/readfile中。

 4. simulator配置

simulator = Simulator(
    board=board,
    on_exit_event={
        ExitEvent.EXIT : (func() for func in [processor.switch]),
    },
)

 参数on_exit_event用于指定指令m5 exit执行后触发的事件,默认为退出操作系统。这里表示第一个m5 exit指令执行将触发processor.switch函数,即进行CPU的切换,第二个m5 exit指令使操作系统正常退出。

运行过程

1. 执行配置脚本

打开终端,在gem5/目录下执行:

./build/X86/gem5.opt configs/example/gem5_library/x86-ubuntu-run-with-kvm.py

 等待一段时间后终端界面保持不变(进入等待接入状态)

 2. 使用m5term远程连接

新建一个终端,进入目录gem5/util/term下,执行指令:

m5term localhost 3456

 将启动m5终端,并接入之前运行的gem5配置系统。

等待指令文件中全部指令执行完成后结束仿真。

注意:如果是首次所用m5term,需要先在目录gem5/util/term下执行make。

3. 结果

最终的结果保存在gem5/m5out文件夹中:

  • board_pc_com_1.device:终端输出(官方教程有误)
  • stats.txt:仿真结果数据
  • config.ini, config.json:模拟处理器的配置

总结

想要完成一个自定义处理器的全系统仿真,可依照以上配置文件编写流程和执行流程照猫画虎。难点在于配置和实现不同的处理器架构

  1. gem5标准库的利用和扩展。这个教程中使用了一个SimpleSwitchableProcessor类,实例化了一个双核处理器。可以对gem5标准库进行更深入的了解,看是否存在可直接利用的类,若没有,则需要学习如何编写实现满足自身需求的类。
  2. 还需要对各种组件的具体实现进行深入学习,例如:X86Board中的processor、memory、cache等是如何连接,如何在其中添加新的组件等。

参考链接:

gem5: X86 Full-System Tutorial

gem5模拟器入门(一) - 知

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值