之前都是在从RISC-V的基础上进行改动,最近想自定制一个指令集,但是感觉对gem5的熟悉度不够,对它的运作方式理解也不是很到位,准备从se.py开始看看源码,观察一个顺序的单核RISC-V是怎么样进行模拟的,顺便记录一下。理解有误的地方欢迎大家指正。

一、se.py

前面部分的代码主要使用于将args中的参数进行处理,如:

Options.addCommonOptions(parser)
Options.addSEOptions(parser)
(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(args)

Simulation.setCPUClass()会从默认的几个CPU模型中通过输入的参数进行选择,如果要使用到改变的模型可以像我这样:

if args.rand == 1:CPUClass = O3_riscv.O3_RISCVFutureClass = Nonetest_mem_mode = CPUClass.memory_mode()
else:(CPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(args)

当然前面要声明添加rand参数以及导入头文件,当输入了–rand = 1 后就会选择我在RISC-V的基础上配置的O3_RISCV。
之后一大堆的system.**的赋值,在官方教程里也有写,就是在构建整个系统,这里面包括了之前设置的CPUClass,以及设置cache的参数:

CacheConfig.config_cache(args, system)
root = Root(full_system = False, system = system)

Root()在src/sim/Root.py。这里会调用SimObject中初始化的方法来初始化一个Root,后续在simulate.py中使用到的Root就是当前创建的这个。Root.py中部分代码:

Root.py中部分代码:class Root(SimObject):_the_instance = Nonedef __new__(cls, **kwargs):if Root._the_instance:fatal("Attempt to allocate multiple instances of Root.")return NoneRoot._the_instance = SimObject.__new__(cls)return Root._the_instance

重要的是后面这个

Simulation.run(args, root, system, FutureClass)

将所有设置好的参数放入Simulation.run()中。

二、Simulate.py()

主要就是后面的run()函数,run函数看起来挺多的,将其中主要的部分挑选出来,把这次都用不到的都删掉以及改了一下得到下面的几个部分:

def run(options, root, testsys, cpu_class):np = options.num_cpusif cpu_class:switch_cpus = [cpu_class(switched_out=True, cpu_id=(i))for i in range(np)]for i in range(np):switch_cpus[i].system = testsysswitch_cpus[i].workload = testsys.cpu[i].workloadswitch_cpus[i].clk_domain = testsys.cpu[i].clk_domainswitch_cpus[i].progress_interval = \testsys.cpu[i].progress_intervalswitch_cpus[i].isa = testsys.cpu[i].isa# simulation periodtestsys.switch_cpus = switch_cpusswitch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in range(np)]

这部分主要还是设置好switch_cpu_list。对于单核来说np=1,那么此时switch_cpu_list和testsys是一样的。

   if cpu_class:print("Switch at curTick count:%s" % str(10000))exit_event = m5.simulate(10000)print("Switched CPUS @ tick %s" % (m5.curTick()))m5.switchCpus(testsys, switch_cpu_list)exit_event = benchCheckpoints(options, m5.MaxTick, cptdir)             #do  #maxtick = m5.MaxTickprint('Exiting @ tick %i because %s' %(m5.curTick(), exit_event.getCause()))if exit_event.getCode() != 0:print("Simulated exit code not 0! Exit code is", exit_event.getCode())

第三行中的m5.simulate位于src/python/m5/simulate.py

def simulate(*args, **kwargs):global need_startupif need_startup:root = objects.Root.getInstance()          #得到之前初始化的Rootfor obj in root.descendants(): obj.startup()

gem5是事件驱动的,所以我认为,这里的循环里的startup()就是驱动部件一次,结合起来就是依次驱动系统中的每个部件。
root.descendants():

    def descendants(self):yield selffor (name, child) in sorted(self._children.items()):for obj in child.descendants():yield obj

yield用法参考:https://blog.csdn.net/mieleizhi0522/article/details/82142856。总之就是运行一次就选择进一步的孩子模块。
startup()位于src/cim/root.cc

Root::startup()
{timeSyncEnable(params().time_sync_enable);
}其中timeSyncEnable():Root::timeSyncEnable(bool en)
{if (en == _enabled)return;_enabled = en;if (_enabled) {// Get event going.Tick periods = ((curTick() + _periodTick - 1) / _periodTick);Tick nextPeriod = periods * _periodTick;schedule(&syncEvent, nextPeriod);} else {// Stop event.deschedule(&syncEvent);}
}
负责事件在线程调度的运行与停止
schedule(),deschedule()都在src/sim/eventq.hh中

再回到之前的simulate():

        need_startup = False# Python exit handlers happen in reverse order.# We want to dump stats last.atexit.register(stats.dump)     #生成json# register our C++ exit callback function with Pythonatexit.register(_m5.core.doExitCleanup)       #退出内核

atexit.register()用于注册函数在程序退出时以注册顺序逆序执行,参考https://blog.csdn.net/hwb18253164494/article/details/53453694

        # Reset to put the stats in a consistent state.stats.reset() #重置stats文件if _drain_manager.isDrained():_drain_manager.resume()

在src/sim/drain.cc中有

_drain_manager = _m5.drain.DrainManager.instance()
bool isDrained() const { return _state == DrainState::Drained; }
总之就是重置所有的部件
    # We flush stdout and stderr before and after the simulation to ensure the# output arrive in order.sys.stdout.flush()        #sys.stdout.flush()的作用就是显示地让缓冲区的内容输出。sys.stderr.flush()sim_out = _m5.event.simulate(*args, **kwargs)           ###还没找到,下次再找吧sys.stdout.flush()sys.stderr.flush()return sim_out

stdout与stderr的区别:https://blog.csdn.net/jasonchen_gbd/article/details/80795645

gem5源码解读se.py以及simulate.py(一)相关推荐

  1. faster rcnn源码解读(三)train_faster_rcnn_alt_opt.py

    转载自:faster rcnn源码解读(三)train_faster_rcnn_alt_opt.py - 野孩子的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/u ...

  2. 利用yolov5训练自己的数据集; yolov5的安装与使用 ; yolov5源码解读

    *免责声明: 1\此方法仅提供参考 2\搬了其他博主的操作方法,以贴上路径. 3* 场景一:Anconda环境基本操作 场景二:yolov5的使用 场景三:yolo v5训练自己的数据集 场景四:yo ...

  3. faster rcnn源码解读(四)之数据类型imdb.py和pascal_voc.py(主要是imdb和roidb数据类型的解说)

    转载自:faster rcnn源码解读(四)之数据类型imdb.py和pascal_voc.py(主要是imdb和roidb数据类型的解说) - 野孩子的专栏 - 博客频道 - CSDN.NET ht ...

  4. Ubuntu 16.04下Caffe-SSD的应用(四)——ssd_pascal.py源码解读

    前言 caffe-ssd所有的训练时的参数,全部由ssd_pascal.py来定义,之后再去调用相关的脚本和函数,所以想要训练自己的数据,首先要明白ssd_pascal.py各个定义参数的大体意思. ...

  5. 小白学习pytorch源码(二):setup.py最详细解读

    小白学习pytorch源码(二) pytorch setup.py最全解析 setup.py与setuptools setup.py最详细解读 setup.py 环境检查 setup.py setup ...

  6. PTMs:QLoRA技巧之源码解读(qlora.py文件)—解析命令与加载参数→数据预处理→模型训练+评估+推理

    PTMs:QLoRA技巧之源码解读(qlora.py文件)-解析命令与加载参数→数据预处理→模型训练+评估+推理 目录 QLoRA技巧之源码解读(qlora.py文件)-解析命令与加载参数→数据预处理 ...

  7. 【YOLOV5-5.x 源码解读】metrics.py

    目录 前言 0.导入需要的包 1.fitness 2.ap_per_class.compute_ap 2.1.ap_per_class 2.2.compute_ap 3.ConfusionMatrix ...

  8. Bert系列(二)——源码解读之模型主体

    本篇文章主要是解读模型主体代码modeling.py.在阅读这篇文章之前希望读者们对bert的相关理论有一定的了解,尤其是transformer的结构原理,网上的资料很多,本文内容对原理部分就不做过多 ...

  9. Bert系列(三)——源码解读之Pre-train

    https://www.jianshu.com/p/22e462f01d8c pre-train是迁移学习的基础,虽然Google已经发布了各种预训练好的模型,而且因为资源消耗巨大,自己再预训练也不现 ...

  10. PyTorch 源码解读之即时编译篇

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 作者丨OpenMMLab 来源丨https://zhuanlan.zhihu.com/ ...

最新文章

  1. 你还在认为 count(1) 比 count(*) 效率高?
  2. 批量处理word文件内容_用python批量提取word文件信息,导出到excel文件
  3. linux常用文本编辑器nano/vi/vim
  4. 嵌入式 Hi3515视频编码(H.264)笔记
  5. 微软算法100题58 从尾到头输出链表(java)
  6. python中的argparse包——用于解析命令行参数
  7. Acwing第 4 场周赛【未完结】
  8. C#泛型委托,匿名方法,匿名类
  9. Java实现获取HDFS子目录数量_Java实现读取HDFS目录
  10. c++中的运算符异或^,与,或|
  11. Windows下编译安装kafka管理工具 kafka-manager (详细)
  12. jquery easyui datagrid改变某行的值
  13. 手撕代码之快速排序算法(简单明了)
  14. c语言中按字节运算,C语言中位运算的巧用
  15. DHCP中继数据包互联网周游记
  16. linux 主机支持远程唤醒_linux 通过wol远程开机【转】
  17. 对接码是什么意思_聊聊API:API对接是什么意思 API接口程序介绍
  18. c语言判断sjis编码,loadrunner Web_类函数之web_sjis_to_euc_param()
  19. Unity读取内部、外部资源详解
  20. 单片机原理及接口技术第1章

热门文章

  1. NVIDIA Nsight Systems 入门及使用
  2. 2007年1月11日~2022年1月11日,我在 SAP 成都研究院这15年
  3. 【九天教您南方cass 9.1】 14 坐标数据的纠正
  4. 第四方支付 java代码_第三方支付平台 API聚合支付系统 云支付源码 PHP第四方pi支付...
  5. 服务器显示器分辨率,屏幕分辨率修改
  6. #计算机网络#学习笔记-常用端口详解
  7. c 语言tcp实现电子词典项目
  8. 计算机哪个信息是硬盘大小,查看电脑硬盘大小_电脑硬盘大小怎么看
  9. 非常难得的 CMOS sensor 工作原理的深入技术科普
  10. 测试渗透前置知识-行业术语