GEM5教程--修改和拓展gem5(一)

一、设置开发环境

1、gen5样式准则

编码样式文档

修改任何开源项目时,请务必遵循项目的样式准则。 gem5样式的详细信息可以在如上网站找到。

为了帮助您遵循样式准则,gem5包含一个脚本,该脚本在您在git中提交变更集时运行。 首次构建gem5时,SCons应该将此脚本自动添加到您的.git / config文件中。 请不要忽略这些警告/错误。 但是,在极少数情况下,如果您尝试提交不符合gem5样式准则的文件(例如,gem5源代码树之外的内容),则可以使用git选项–no-verify跳过运行 样式检查器。

样式指南的主要内容是:

  • Use 4 spaces, not tabs
  • Sort the includes
  • Use capitalized camel case for class names, camel case for member variables, and underscores for local variables.
  • Document your code
2、git 分支:

大多数使用gem5开发的人都使用git的分支功能来跟踪他们的更改。 这使得将更改提交回gem5非常简单。 另外,使用分支可以使其他人进行的新更改更容易更新gem5,同时将您自己的更改分开。 Git Book中有一章很棒,描述了如何使用分支的细节。

二、创建一个非常简单的SimObject

gem5中几乎所有对象都继承自基本SimObject类型。 SimObjects将主接口导出到gem5中的所有对象。 SimObject是包装的C ++对象,可从Python配置脚本访问。

SimObjects可以具有许多参数,这些参数是通过Python配置文件设置的。 除了简单的参数(例如整数和浮点数)外,它们还可以具有其他SimObjects作为参数。 这使您可以创建复杂的系统层次结构,例如真实的计算机。

这一部分,我们将逐步创建一个简单的“ HelloWorld” SimObject。 目的是向您介绍如何创建SimObject,以及所有SimObject所需的样板代码。 我们还将创建一个简单的Python配置脚本来实例化SimObject。

1、为您的新SimObject创建一个Python类

每个SimObject都有一个与之关联的Python类。 此类Python描述了可以从Python配置文件控制的SimObject的参数。 对于简单的SimObject,我们将开始时不使用任何参数。 因此,我们只需要为SimObject声明一个新类并设置其名称和C ++标头即可为SimObject定义C ++类。

我们能创建一个文件 HelloObject.py, 在 src/learning_gem5

from m5.params import *
from m5.SimObject import SimObject

class HelloObject(SimObject):
    type = 'HelloObject'
    cxx_header = "learning_gem5/hello_object.hh"

不需要类型与类的名称相同,但这是约定。 类型是您与此Python SimObject包装的C ++类。 仅在特殊情况下,类型和类名才可以不同。

cxx_header是一个文件,其中包含用作类型参数的类的声明。 同样,惯例是将SimObject的名称全部使用小写和下划线,但这只是惯例。 您可以在此处指定任何头文件。

2、用C ++实现SimObject

接下来,我们创建hello_object.hh和hello_object.cc来实现hello对象。

(1)我们将从C ++对象的头文件开始。 按照约定,gem5将所有头文件包装在#ifndef /#endif中,并带有文件名及其所在目录,因此没有循环包含。

我们在文件中唯一需要做的就是声明我们的类。 由于HelloObject是SimObject,因此它必须继承自C ++ SimObject类。 大多数情况下,您的SimObject的父级将是SimObject的子类,而不是SimObject本身。

SimObject类指定许多虚函数。 但是,这些功能都不是纯虚拟的,因此在最简单的情况下,除了构造函数外,无需实现任何功能。

所有SimObjects的构造函数都假定它将接受一个参数对象。 这个参数对象是由构建系统自动创建的,并且基于SimObject的Python类,就像我们上面创建的那样。 此参数类型的名称是根据对象的名称自动生成的。 对于我们的“ HelloObject”,参数类型的名称为“ HelloObject ** Params **”。

下面列出了我们的简单头文件所需的代码:

#ifndef __LEARNING_GEM5_HELLO_OBJECT_HH__
#define __LEARNING_GEM5_HELLO_OBJECT_HH__

#include "params/HelloObject.hh"
#include "sim/sim_object.hh"

class HelloObject : public SimObject
{
  public:
    HelloObject(HelloObjectParams *p);
};

#endif // __LEARNING_GEM5_HELLO_OBJECT_HH__

(2)接下来,我们需要在.cc文件中实现两个功能,而不仅仅是一个。 第一个函数是HelloObject的构造函数。 在这里,我们只是将参数对象传递给SimObject父对象,并输出“ Hello world!”。
通常,您永远不会在gem5中使用std :: cout。 相反,您应该使用调试标志。 在之后的教程中,我们将对其进行修改以改为使用调试标志。 但是,由于它很简单,我们暂时仅使用std :: cout。

#include "learning_gem5/hello_object.hh"

#include <iostream>

HelloObject::HelloObject(HelloObjectParams *params) :
    SimObject(params)
{
    std::cout << "Hello World! From a SimObject!" << std::endl;
}

为了使SimObject完整,我们还必须实现另一个功能。 我们必须为从SimObject Python声明隐式创建的参数类型实现一个函数,即create函数。 该函数仅返回SimObject的新实例。 通常,此功能非常简单(如下所示):

如果忘记为SimObject添加create函数,则在编译时会出现链接器错误。 它将类似于以下内容:

build/X86/python/m5/internal/param_HelloObject_wrap.o: In function `_wrap_HelloObjectParams_create':
/local.chinook/gem5/gem5-tutorial/gem5/build/X86/python/m5/internal/param_HelloObject_wrap.cc:3096: undefined reference to `HelloObjectParams::create()'
collect2: error: ld returned 1 exit status
scons: *** [build/X86/gem5.opt] Error 1
scons: building terminated because of errors.

对“ HelloObjectParams :: create()”的未定义引用意味着您需要为SimObject实现create函数。

3、注册SimObject和C ++文件

为了编译C ++文件和解析Python文件,我们需要将这些文件告知构建系统。 gem5使用SCons作为构建系统,因此您只需在目录中使用SimObject的代码创建一个SConscript文件。 如果该目录已经有一个SConscript文件,只需将以下声明添加到该文件中。

该文件只是普通的Python文件,因此您可以在该文件中编写所需的任何Python代码。 一些脚本可能变得非常复杂。 gem5利用此功能自动为SimObjects创建代码,并编译特定于域的语言,例如SLICC和ISA语言。

要编译新的SimObject,只需在src / learning_gem5目录中创建一个名称为“ SConscript”的新文件。 在此文件中,您必须声明SimObject和.cc文件。 以下是必需的代码:

Import('*')

SimObject('HelloObject.py')
Source('hello_object.cc')
4、(重新)构建gem5

要编译和链接新文件,您只需要重新编译gem5。 下面的示例假设您使用的是x86 ISA,但是我们的对象中不需要ISA,因此,gem5的任何ISA都可以使用。

scons build/X86/gem5.opt
5、创建配置脚本以使用新的SimObject

既然您已经实现了SimObject,并且已将其编译到gem5中,则需要创建或修改Python配置文件以实例化对象。 由于您的对象非常简单,因此不需要系统对象! 除Root对象外,不需要CPU,缓存或其他任何东西。 所有gem5实例都需要一个Root对象。

(1)逐步创建一个非常简单的配置脚本,首先,导入m5和所有已编译的对象:

import m5
from m5.objects import *

(2)接下来,您必须根据所有gem5实例的要求实例化Root对象:

root = Root(full_system = False)

(3)现在,您可以实例化创建的HelloObject。 您需要做的就是将Python称为“构造函数”。 稍后,我们将研究如何通过Python构造函数指定参数。 除了创建对象的实例化之外,还需要确保它是根对象的子代。 在C ++中仅实例化作为Root对象的子对象的SimObject:

root.hello = HelloObject()

(4)最后,您需要在m5模块上调用实例化并实际运行仿真:

m5.instantiate()

print("Beginning simulation!")
exit_event = m5.simulate()
print('Exiting @ tick {} because {}'
  .format(m5.curTick(), exit_event.getCause()))

运行结果如下:

运行结果

GEM5系列教程索引

GEM5教程–gem5开始之旅(一)

GEM5教程–gem5开始之旅(二)

GEM5教程–修改和拓展gem5(一)

GEM5教程–修改和拓展gem5(二)

GEM5教程–修改和拓展gem5(三)

GEM5教程–修改和拓展gem5(四)

GEM5教程-互联网络

GEM5教程-Garnet

gem5学习基础完整版,介绍了gem5环境的安装,以及些基本概念。 gem5仿真器是用于计算机系统体系结构研究的模块化平台,涵盖系统级体系结构以及处理器微体系结构。1、多个可互换的CPU型号。 gem5提供了四种基于解释的CPU模型:简单的单CPI CPU; 有序CPU的详细模型无序CPU的详细模型。 这些CPU模型使用通用的高级ISA描述。 此外,gem5具有基于KVM的CPU,该CPU使用虚拟化来加速仿真。 2、完全集成的GPU模型,可以执行真实计算机ISA,并支持与主机CPU共享的虚拟内存。 3、NoMali GPU模型。 gem5带有集成的NoMali GPU模型,该模型与LinuxAndroid GPU驱动程序堆栈兼容,因此无需进行软件渲染。 NoMali GPU不产生任何输出,但可以确保以CPU为中心的实验产生代表性的结果。 4、事件驱动的内存系统。 gem5具有详细的,事件驱动的内存系统,包括高速缓存,交叉开关,探听过滤器以及快速而准确的DRAM控制器模型,用于捕获当前新兴内存的影响,例如内存。 LPDDR3 / 4/5,DDR3 / 4,GDDR5,HBM1 / 2/3,HMC,WideIO1 / 2。 可以灵活地布置组件,例如,以具有异构存储器的复杂的多级非均匀高速缓存层次结构来建模。 5、基于跟踪的CPU模型,可播放弹性跟踪,这些跟踪是由附着到乱序CPU模型的探针生成的依赖项定时注释的跟踪。 跟踪CPU模型的重点是以快速,合理的方式而不是使用详细的CPU模型来实现内存系统(高速缓存层次结构,互连主内存)的性能探索。 6、异构异构多核。 可以将CPU模型缓存组合到任意拓扑中,从而创建同构异构的多核系统。 MOESI侦听缓存致性协议可保持缓存致性。 7、多种ISA支持。 gem5将ISA语义与其CPU模型解耦,从而实现对多个ISA的有效支持。 目前gem5支持Alpha,ARM,SPARC,MIPS,POWER,RISC-Vx86 ISA。 有关更多信息,请参见支持的体系结构。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值