使用gem5标准库构建“HelloWorld”的例子

本文介绍如何使用gem5组件创建非常基本的仿真:仿真的配置是单核处理器组成的系统,并且该处理器以原子模式运行,处理器与主存储器直接相连,没有缓存、I/O或其他组件。系统在系统调用仿真(SE)模式下运行X86二进制文件,该二进制文件通过gem5-resources获取,并在执行时将“HelloWorld!”字符串打印到标准输出。

首先需要先编译gem5,其用于模拟X86指令集架构(ISA):

# 在gem5的根目录下
scons build/X86/gem5.opt -j <number of threads>

然后新创建一个Python文件(名为“hello-world.py”,下文都基于此文件),该文件中的前几行用于导入所需模块:

from gem5.components.boards.simple_board import SimpleBoard
from gem5.components.cachehierarchies.classic.no_cache import NoCache
from gem5.components.memory.single_channel import SingleChannelDDR3_1600
from gem5.components.processors.simple_processor import SimpleProcessor
from gem5.components.processors.cpu_types import CPUTypes
from gem5.resources.resource import Resource
from gem5.simulate.simulator import Simulator

上述所有的库都包含在编译过的gem5二进制文件中,所以用户无需从其它地方获取。“from gem5.”表示从gem5的标准库导入,开头是“from gem5.components”的行表示从gem5组件包导入组件,开头是“from gem5.resources”和“from gem5.simulate”的行则分别表示从资源包和模拟包导入资源和模拟,所有的这些包、组件、资源和模拟都是gem5标准库的一部分。

接下来,需要指定系统。gem5库要求用户指定四个主要组件:板、cache层次结构、内存系统和处理器,首先指定cache层次结构:

cache_hierarchy = NoCache()

在gem5库中的缓存层次结构是一个广义术语,指代处理器内核和主内存之间存在的任意全部内容。这里使用NoCache()表示声明的系统没有缓存层次结构,即无cache,处理器直接连接到主存储器。接下来继续声明内存系统:

memory = SingleChannelDDR3_1600("1GiB")

gem5.components.memory中提供许多内存组件供用户选择,本例选用单通道DDR3 1600内存,大小为1GiB。从技术上将,此处这个大小是可选的,如果SingleChannelDDR3_1600的大小未被设置,则默认为8GiB。紧接着再考虑处理器:

processor = SimpleProcessor(cpu_type=CPUTypes.ATOMIC, num_cores=1)

每个处理器(processor)是gem5.components中的一个对象,该对象包含许多特定或不同类型(ATOMIC, TIMING, KVM, O3等)的gem5 CPU核心。 本例所使用的SimpleProcessor处理器是CPU内部所有核心都属于同一类型的处理器,它需要cpu类型和核心数(cpu_type和num_cores)两个参数,本例核心数设置为1。最后,还需要为gem5仿真指定所使用的板(board):

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

虽然每块板的构造函数可能有所不同,但它们通常都会要求用户指定处理器、内存系统、缓存层次结构和使用的时钟频率。 本例中使用的SimpleBoard板是一个非常基础的系统,它没有 I/O,仅支持SE模式,且只能使用“经典 (classic)”缓存层次结构。
至此脚本就已经完成了仿真系统所要求的指定,然而,为了使仿真的运行有意义,还必须指定待仿真系统运行时的工作负载,因此本例还增加下面几行:

binary = Resource("x86-hello64-static")
board.set_se_binary_workload(binary)

其中Resource类使用一个字符串指定要从gem5-resources中获取的用于仿真的资源,gem5的全部资源都可以在官方gem5的资源网站上找到。

如果主机系统上没有该资源,则gem5自动下载该资源。 本例使用一个名为“x86-hello-64-static”的资源,它是一个64位x86架构下静态编译的二进制文件,能够将“Hello World!”字符串打印到标准输出(stdout)。 资源指定了以后,还需要通过开发板的set_se_binary_workload函数设置工作负载。 顾名思义,set_se_binary_workload是一个用于设置要在系统调用执行(Syscall Execution)模式下执行的二进制文件的函数。

以上就是用户设置自己的仿真时所需要的全部内容,现在只需要简单地构建并运行Simulator仿真器即可:

simulator = Simulator(board=board)
simulator.run()

另外请注意,仿真器( Simulator )模块目前还处于测试状态(beta版本),因此其 API 可能会在下一版本发布时发生改变。

总而言之,用户脚本应该看起来像下面这个样子:

# 1、导入组件库
from gem5.components.boards.simple_board import SimpleBoard
from gem5.components.cachehierarchies.classic.no_cache import NoCache
from gem5.components.memory.single_channel import SingleChannelDDR3_1600
from gem5.components.processors.simple_processor import SimpleProcessor
from gem5.components.processors.cpu_types import CPUTypes
from gem5.resources.resource import Resource
from gem5.simulate.simulator import Simulator


# 2、获取组件
cache_hierarchy = NoCache()
memory = SingleChannelDDR3_1600("1GiB")
processor = SimpleProcessor(cpu_type=CPUTypes.ATOMIC, num_cores=1)

# 3、将组件添加到“板”
board = SimpleBoard(
    clk_freq="3GHz",
    processor=processor,
    memory=memory,
    cache_hierarchy=cache_hierarchy,
)

# 4、设置工作负载
binary = Resource("x86-hello64-static")
board.set_se_binary_workload(binary)

# 5、设置仿真器并运行仿真
simulator = Simulator(board=board)
simulator.run()

本例可以使用以下命令执行:

./build/X86/gem5.opt hello-world.py

如果一切设置都正确,那么输出应如下所示:

...

warn: The simulate package is still in a beta state. The gem5 project does not guarantee the APIs within this package will remain consistent across upcoming releases.
Global frequency set at 1000000000000 ticks per second
build/X86/mem/mem_interface.cc:791: warn: DRAM device capacity (8192 Mbytes) does not match the address range assigned (1024 Mbytes)
0: board.remote_gdb: listening for remote gdb on port 7000
build/X86/sim/simulate.cc:194: info: Entering event queue @ 0.  Starting simulation...
build/X86/sim/syscall_emul.hh:1014: warn: readlink() called on '/proc/self/exe' may yield unexpected results in various settings.
      Returning '/scr/bbruce/.cache/gem5/x86-hello64-static'
build/X86/sim/mem_state.cc:443: info: Increasing stack size by one page.
Hello world!

显然用户可以改变板的参数实现对其他设计的测试, 例如,如果想测试一个TIMING CPU的设置,这里也可以将处理器更改为:

processor = SimpleProcessor(cpu_type=CPUTypes.TIMING, num_cores=1)

只需要做这一处更改,gem5标准库就会根据需要对设计进行重新配置。

再举一个组件更换的例子,本例中使用的NoCache的无缓存结构,也可以更换为其它经典的缓存层次结构,例如更换为PrivateL1CacheHierarchy的缓存层次结构。为此可以更改cache_hierarchy参数如下:

# 首先导入所需的cache层次结构
from gem5.components.cachehierarchies.classic.private_l1_cache_hierarchy import PrivateL1CacheHierarchy

...

# 然后进行设置
cache_hierarchy = PrivateL1CacheHierarchy(l1d_size="32kB", l1i_size="32kB")

这里请注意,PrivateL1CacheHierarchy需要用户来指定待构造的L1数据缓存和指令缓存的大小,无需更改设计的其他部分,gem5标准库会根据要求自动包含相应的缓存层次结构。

最后,回顾一下本教程中的内容:

  • 系统由gem5组件包使用处理器、缓存层次结构、内存系统和板组件构建。
  • 通常而言,相同类型的组件都尽可能的实现了互换。例如,可以在设计中换入和换出不同的缓存层次结构组件,而无需再次重新配置其它组件。
  • 板包含有设置工作负载的函数。
  • 资源包可用于从gem5-resources获取预构建的资源, 这些通常是可以通过工作负载函数设置运行的工作负载。
  • 模拟(simulate)包用于在gem5仿真中运行板。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值