搭建gem5和NVM
搭建环境
主要参考资料
资源下载
由于hg挂了,而且我用的是云机,很多国内的流量无法clone,只好下好了上传,这里整理了过程中用到的所有资源
步骤流程
路径说明
+-- nvmain
|
+-- gem5
|
+-- fs-image
|
+-- benchmark
它们是同一路径!!!
正式开始
安装nvm
wget https://bitbucket.org/mrp5060/nvmain/get/9c0e87b164bc.zip -O nvmain.zip
unzip nvmain.zip
mv mrp5060-nvmain-9c0e87b164bc nvmain
安装scon
安装编译工具scons
sudo apt-get install scons
编译NVMain
编译NVMain,其中编译的类型可以选择fast|debug|prof三种的任意一种,这里我们选用fast
scons --build-type=fast
这里编译是一定会报错的,但是要编译了才有build文件,别直接到下面去找文件改
如果在编译的过程中,报了如下的错误,无须紧张,这只是个小问题,是因为我们暂时还没有用到gem5,所以只需将这个报错的那一行代码注释即可.
scons: Reading SConscript files ...
ImportError: No module named gem5_scons:
File "/home/greek/master/experiment/nvmain/SConstruct", line 253:
SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir)
File "/usr/lib/scons/SCons/Script/SConscript.py", line 614:
return method(*args, **kw)
File "/usr/lib/scons/SCons/Script/SConscript.py", line 551:
return _SConscript(self.fs, *files, **subst_kw)
File "/usr/lib/scons/SCons/Script/SConscript.py", line 256:
call_stack[-1].globals)
File "/home/greek/master/experiment/nvmain/build/SConscript", line 36:
from gem5_scons import Transform
具体的解决办法是将nvmain/build/SConscript中的第36行注释
# from gem5_scons import Transform # 这行注释
注意!我们后面还要修改回来,后面会讲,这里只是为了让你心里有谱
解决错误之后,再重新编译
nvm测试
指定配置文件,指定测试文件,周期, 命令的格式为: ./nvmain CONFIG_FILE TRACE_FILE [Cycles [PARAM=value]]
我们这里的测试命令如下
./nvmain.fast Config/PCM_ISSCC_2012_4GB.config Tests/Traces/hello_world.nvt 1000000
测试结果
i0.defaultMemory.channel0.FRFCFS-WQF.maximum_reads_during_drain 0
i0.defaultMemory.channel0.FRFCFS-WQF.starvation_precharges 4704
i0.defaultMemory.channel0.FRFCFS-WQF.averageLatency 86.4423
i0.defaultMemory.channel0.FRFCFS-WQF.averageQueueLatency 2088.42
i0.defaultMemory.channel0.FRFCFS-WQF.averageTotalLatency 2174.86
i0.defaultMemory.channel0.FRFCFS-WQF.measuredLatencies 26485
i0.defaultMemory.channel0.FRFCFS-WQF.measuredQueueLatencies 26485
i0.defaultMemory.channel0.FRFCFS-WQF.measuredTotalLatencies 26485
i0.defaultMemory.channel0.FRFCFS-WQF.simulation_cycles 1000000
i0.defaultMemory.channel0.FRFCFS-WQF.wakeupCount 54116
i0.defaultMemory.totalReadRequests 13933
i0.defaultMemory.totalWriteRequests 12608
i0.defaultMemory.successfulPrefetches 0
i0.defaultMemory.unsuccessfulPrefetches 0
Exiting at cycle 5000000 because simCycles 5000000 reached.
Note: 57 requests still in-flight.
安装gem5
在Ubuntu上,您可以使用以下命令安装所有必需的依赖项。要求详细说明如下。
安装依赖(若干)
sudo apt install build-essential git m4 scons zlib1g zlib1g-dev libprotobuf-dev protobuf-compiler libprotoc-dev libgoogle-perftools-dev python-dev python
正常情况下这些东西不是全都做了镜像的(我只测试了阿里和腾讯云),但是保证基础的c++等(详情见文档)是必要的boost装了会好很多systemc可以用了
安装依赖库protobuf-compiler
sudo apt-get install protobuf-compiler
提前做好措施 (因为内存不足 使用交换分区来解决)
原因其实也很简单:学生机只有1G,必定是不够的,编译过程中常常会自动kill
sudo dd if=/dev/zero of=/swapfile bs=64M count=16
#count的大小就是增加的swap空间的大小,64M是块大小,所以空间大小是bs*count=1024MB
sudo mkswap /swapfile
#把刚才空间格式化成swap格式
sudo swapon /swapfile
#使用刚才创建的swap空间
按理来说是应该还回去的,但是考虑到后面经常挂,就不还了
解压并重命名
sudo unzip gem5-master.zip
ubuntu@VM-0-5-ubuntu:~/skywf$ ls
config-x86.tar.bz2 gem5-master.zip mrp5060-nvmain-7be1ae0275cb.zip nvmain.zip zlib-1.2.11.tar.gz
gem5-master m5_system_2.0b3.tar.bz2 nvmain x86-system.tar.bz2
ubuntu@VM-0-5-ubuntu:~/skywf$ mv gem5-master gem5
ubuntu@VM-0-5-ubuntu:~/skywf$ ls
config-x86.tar.bz2 gem5-master.zip mrp5060-nvmain-7be1ae0275cb.zip nvmain.zip zlib-1.2.11.tar.gz
gem5 m5_system_2.0b3.tar.bz2 nvmain x86-system.tar.bz2
开始编译
漫长的等待,大概1个小时吧
$<2> [ CXX] X86/cpu/kvm/x86_cpu$<2>.cc$<2> -> $<2>.o$<2>
$<2> [ LINK] $<2>$<2> -> $<2>X86/cpu/kvm/lib.o.partial$<2>
$<2> [ CXX] X86/base/date$<2>.cc$<2> -> $<2>.o$<2>
$<2> [ LINK] $<2>$<2> -> $<2>X86/gem5.opt$<2>
scons: done building targets.
说明编译好了
Gem5的SE测试
- 用来运行单个应用,一系列指令在MP/SMT上
- 建模用户可见的ISA和常见的系统调用
- 模拟系统调用,通过调用主机操作系统
- 简单的地址翻译,没有调度
./build/X86/gem5.opt configs/example/se.py -c tests/test-progs/hello/bin/x86/linux/hello
Gem5的FS测试
FS测试
能够启动完整的操作系统
建模硬件设备
中断,异常,故障处理函数
若没有使用我提供的包,需要自己下载
下载X86全系统对应的文件,一定要下载自己编译架构的对应文件
部分架构存在不可知的bug,没事儿别去探险
wget http://www.m5sim.org/dist/current/x86/x86-system.tar.bz2
解压文件,同时将解压后的文件夹放入同一目录fs-image
tar vxfj x86-system.tar.bz2
mkdir fs-image
mv binaries fs-image
mv disks fs-image
下载alpha对应的全系统文件,里面包含linux-bigswap2.img,这个是运行的一个必须文件.下载之后,解压文件,同时将文件拷贝到fs-image/disks目录下,可以理解为专门存放镜像文件的目录
wget http://www.m5sim.org/dist/current/m5_system_2.0b3.tar.bz2
tar vxfj m5_system_2.0b3.tar.bz2
cp m5_system_2.0b3/disks/linux-bigswap2.img fs-image/disks
若使用了我提供的包,直接解压即可
sudo tar vxfj x86-system.tar.bz2
mkdir fs-image
sudo mv binaries fs-image
sudo mv disks fs-image
sudo tar vxfj m5_system_2.0b3.tar.bz2
sudo cp m5_system_2.0b3/disks/linux-bigswap2.img fs-image/disks
运行FS模拟
./build/X86/gem5.opt configs/example/fs.py
报了如下的错误,这里因为脚本代码中默认了镜像为x86root.img
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "build/X86/python/m5/main.py", line 457, in main
exec(filecode, scope)
File "configs/example/fs.py", line 342, in <module>
test_sys = build_test_system(np)
File "configs/example/fs.py", line 93, in build_test_system
cmdline=cmdline)
File "/home/ubuntu/skywf/gem5/configs/common/FSConfig.py", line 622, in makeLinuxX86System
makeX86System(mem_mode, numCPUs, mdesc, self, Ruby)
File "/home/ubuntu/skywf/gem5/configs/common/FSConfig.py", line 548, in makeX86System
disks = makeCowDisks(mdesc.disks())
File "/home/ubuntu/skywf/gem5/configs/common/Benchmarks.py", line 63, in disks
return [env.get('LINUX_IMAGE', disk('x86root.img'))]
File "/home/ubuntu/skywf/gem5/configs/common/SysPaths.py", line 69, in __call__
.format(self.environment_variable))
IOError: Can't find system files directory, check your M5_PATH environment variable
解决办法
这里有两种解决办法,推荐使用第二种:
- 修改代码gem5/configs/common/Benchmarks.py中,第63行,修改为如下,其中linux-86.img为fs-image/disks目录下的镜像文件
return env.get('LINUX_IMAGE', disk('linux-x86.img'))
- 直接使用参数指定镜像文件,使用参数 --disk-image以及–kernel
./build/X86/gem5.opt configs/example/fs.py --disk-image linux-x86.img --kernel x86_64-vmlinux-2.6.22.9
指定M5_PATH路径,系统会自动从M5_PATH路径中disks和binaries两个目录寻找指定的镜像文件和对应的内核文件.
注意此处需要指定M5_PATH
注意此处x86有大写有小写
其中指定M5_PATH我提供了两种方式,推荐使用第二种
- 修改.basrhc文件,在文件的末尾加入M5_PATH的路径
vim ~/.bashrc
export M5_PATH=$M5_PATH:/home/ubuntu/skywf/fs-image
source ~/.bashrc
注意这里的路径有ubuntu,和centos不太一样
直接在运行命令中动态添加环境变量
M5_PATH=/home/skywf/fs-image ./build/X86/gem5.opt configs/example/fs.py --disk-image linux-x86.img --kernel x86_64-vmlinux-2.6.22.9
注意上面的skywf换成自己的用户名
linux-x86.img为fs-image/disks/目录下文件, x86_64-vmlinux-2.6.22.9为fs-image/binaries/目录下文件,我看网上很多教程将x86_64-vmlinux-2.6.22.9改名为vmlinux,这步的话其实意义不是特别大,不过改了也方便,我这里暂不做修改
可能遇到的问题
- 出现Output file stream not open”: Error while running SE for X86 using gem5
原因是你没有文件操作的权限,可以通过sudo改变777或者直接sudo命令解决
问题解析 Traceback (most recent call last): File "<string>", line 1, in <module> File "build/X86/python/m5/main.py", line 457, in main exec(filecode, scope) File "configs/example/fs.py", line 342, in <module> test_sys = build_test_system(np) File "configs/example/fs.py", line 93, in build_test_system cmdline=cmdline) File "/home/ubuntu/skywf/gem5/configs/common/FSConfig.py", line 622, in makeLinuxX86System makeX86System(mem_mode, numCPUs, mdesc, self, Ruby) File "/home/ubuntu/skywf/gem5/configs/common/FSConfig.py", line 548, in makeX86System disks = makeCowDisks(mdesc.disks()) File "/home/ubuntu/skywf/gem5/configs/common/Benchmarks.py", line 59, in disks return [disk(diskname) for diskname in self.disknames] File "/home/ubuntu/skywf/gem5/configs/common/SysPaths.py", line 69, in __call__ .format(self.environment_variable)) IOError: Can't find system files directory, check your M5_PATH environment variable
M5_PATH路径设置还是有问题,这里有点玄学我还没弄懂,不过用指定动态变量可以解决暂时按下不表。
连接模拟系统
利用gem5系统自带的一个连接程序,在gem5/util/term/目录中,先进行make,生成可执行文件
cd util/term/
make
./m5term localhost 3456
[推荐使用] 直接利用telnet连接系统
telnet localhost 3456
腾讯云默认没有放开这个端口,请到安全组里面自己打开
出现下面这个代表成功连上了
usbcore: registered new interface driver usbhid
drivers/hid/usbhid/hid-core.c: v2.6:USB HID core driver
oprofile: using timer interrupt.
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 10
IPv6 over IPv4 tunneling driver
NET: Registered protocol family 17
EXT2-fs warning: mounting unchecked fs, running e2fsck is recommended
VFS: Mounted root (ext2 filesystem).
Freeing unused kernel memory: 232k freed
INIT: version 2.86 booting
mounting filesystems...
loading script...
Script from M5 readfile is empty, starting bash shell...
(none) / #
退出
这里我依旧使用两种方法,推荐使用第一种方法
在连接的命令行中输入 m5 exit
在连接的命令行中输入 ~.
NVMain和Gem5的集成环境
为啥打补丁
Gem5补丁
首先为了消除NVMain和Gem5版本之间的差异,所以首先需要给Gem5打上补丁.(别听到补丁就觉得畏惧,一开始我有这种感觉,其实后面发现真的没啥).
开打补丁
手动补丁,直接查看补丁的内容,手动修改文件,如下所示为补丁的内容
补丁文件已经在nvmain/patches/gem5目录中给出,nvmain2-gem5-11688+这个是补丁文件的名字,在nvmain/patches/gem5中,以后可能是其他的版本,换成自己的版本补丁名字即可.
ubuntu@VM-0-5-ubuntu:~/skywf/nvmain/patches/gem5$ ls
nvmain2-gem5-11688+
# HG changeset patch
# Parent 78ef8daecd81de0c392034809b3bc155396bf983
gem5: Updated for gem5 revisions 10789+
diff --git a/configs/common/Options.py b/configs/common/Options.py
--- a/configs/common/Options.py
+++ b/configs/common/Options.py
@@ -63,6 +63,12 @@
# being used, and consequently no CPUs, but rather various types of
# testers and traffic generators.
def addNoISAOptions(parser):
+ # Check for extra nvmain configuration override options
+ for arg in sys.argv:
+ if arg[:9] == "--nvmain-":
+ parser.add_option(arg, type="string", default="NULL",
+ help="Set NVMain configuration value for a parameter")
+
parser.add_option("-n", "--num-cpus", type="int", default=1)
parser.add_option("--sys-voltage", action="store", type="string",
default='1.0V',
其实说白了就是增加了三行,咱们手动加上就可以了
只需在gem5/configs/common/Options.py的第82行之后,加入如下三行(有可能是89行,取决于编辑器为vim or nano)
反正只要是在addnoisaoptions下就可以了
for arg in sys.argv:
if arg[:9] == "--nvmain-":
parser.add_option(arg, type="string", default="NULL", help="Set NVMain configuration value for a parameter")
NVMain和Gem5混合编译
在gem5文件夹下(搞到半夜头昏昏在nvmain下弄了半天气死了)
scons EXTRAS=../nvmain build/X86/gem5.opt
发现报错
NameError: global name 'Transform' is not defined:
File "/home/ubuntu/skywf/gem5/SConstruct", line 1269:
SConscript('src/SConscript', variant_dir = variant_path, exports = 'env')
File "/usr/lib/scons/SCons/Script/SConscript.py", line 614:
return method(*args, **kw)
File "/usr/lib/scons/SCons/Script/SConscript.py", line 551:
return _SConscript(self.fs, *files, **subst_kw)
File "/usr/lib/scons/SCons/Script/SConscript.py", line 260:
exec _file_ in call_stack[-1].globals
File "/home/ubuntu/skywf/gem5/build/X86/SConscript", line 618:
SConscript(joinpath(root, 'SConscript'), variant_dir=build_dir)
File "/usr/lib/scons/SCons/Script/SConscript.py", line 614:
return method(*args, **kw)
File "/usr/lib/scons/SCons/Script/SConscript.py", line 551:
return _SConscript(self.fs, *files, **subst_kw)
File "/usr/lib/scons/SCons/Script/SConscript.py", line 260:
exec _file_ in call_stack[-1].globals
File "/home/ubuntu/skywf/gem5/build/X86/nvmain/SConscript", line 88:
MakeInclude('SimInterface/Gem5Interface/Gem5Interface.h')
File "/home/ubuntu/skywf/gem5/build/X86/nvmain/SConscript", line 85:
include_action = MakeAction(MakeIncludeAction, Transform("MAKE INC", 1))
这是因为之前我们删除了一行,现在还原
sudo nano nvmain/build/SConscript
好了接下来又是等待
收获检验
测试,其中混合编译成功的一个重要标志是可以使用–mem-type=NVMainMemory参数来指定主存为NVM
M5_PATH=/home/hsc/fs-image ./build/X86/gem5.opt configs/example/se.py -c tests/test-progs/hello/bin/x86/linux/hello --caches --l2cache --mem-type=NVMainMemory --nvmain-config=../nvmain/Config/PCM_ISSCC_2012_4GB.config
只要你出现这个,就证明你自己的工作ok了
i0.defaultMemory.channel0.FRFCFS-WQF.maximum_read_spacing 0
i0.defaultMemory.channel0.FRFCFS-WQF.total_readqueue_size 0
i0.defaultMemory.channel0.FRFCFS-WQF.average_predrain_readqueue_size 0
i0.defaultMemory.channel0.FRFCFS-WQF.minimum_predrain_readqueue_size 10000000000
i0.defaultMemory.channel0.FRFCFS-WQF.maximum_predrain_readqueue_size 0
i0.defaultMemory.channel0.FRFCFS-WQF.total_reads_during_drain 0
i0.defaultMemory.channel0.FRFCFS-WQF.average_reads_during_drain 0
i0.defaultMemory.channel0.FRFCFS-WQF.minimum_reads_during_drain 10000000000
i0.defaultMemory.channel0.FRFCFS-WQF.maximum_reads_during_drain 0
i0.defaultMemory.channel0.FRFCFS-WQF.starvation_precharges 0
i0.defaultMemory.channel0.FRFCFS-WQF.averageLatency 0
i0.defaultMemory.channel0.FRFCFS-WQF.averageQueueLatency 0
i0.defaultMemory.channel0.FRFCFS-WQF.averageTotalLatency 0
i0.defaultMemory.channel0.FRFCFS-WQF.measuredLatencies 0
i0.defaultMemory.channel0.FRFCFS-WQF.measuredQueueLatencies 0
i0.defaultMemory.channel0.FRFCFS-WQF.measuredTotalLatencies 0
i0.defaultMemory.channel0.FRFCFS-WQF.simulation_cycles 1188
i0.defaultMemory.channel0.FRFCFS-WQF.wakeupCount 0
i0.defaultMemory.totalReadRequests 0
i0.defaultMemory.totalWriteRequests 0
i0.defaultMemory.successfulPrefetches 0
i0.defaultMemory.unsuccessfulPrefetches 0