Chiplet论文阅读—— Methodology for Simulating Multi-chiplet Systems UsingOpen-source Simulators

一、论文总结

二、摘要

为了支持早期的Chiplets系统的设计空间探索,提出了一种基于gem5、snipe、gpgpu-sim等开源模拟器的Chiplets架构模拟方法。

并开源在Github上 https://github.com/FCAS-SCUT/chiplet_simulators

三、背景&目前待解决的问题

Chiplet是后摩尔时代一种很有前途的设计模式,但针对Chiplet的体系结构研究缺乏可靠的模拟器。

1. Chiplets微架构的设计空间比SoC要大得多,因此需要探索的设计更多

主要包括核的组织方式(128核系统可以分为32cores * 4 chiplets、16cores * 8 chiplets等)、互联的拓扑结构内存模型

2. 现有开源的模拟器无法直接用于chiplets系统的模拟,因为以下两个原因:

  • 没有精确的Chiplet间互联模型。现有开源模拟器(如gem5、sniper、Graphite、gpgpu-sim)都是纯网络模拟器(network-only simulator),缺乏详细准确的中介层互连延迟和功率模型{❓意思是仅能够精确模拟chiplet内部多核的互联,对chiplet间的互联模拟不精确吗❓}。

  • 无法进行大规模并行模拟。Multi-Chiplets系统一般具有大量的核,这样的系统模拟起来会很耗时,因此需要通过大规模的并行来加速模拟。虽然Graphite和sniper支持并行模拟,但并不支持精确的互联建模。

四、文章贡献

文章通过集成和修改开源模拟器,提出了一种模拟Multi-Chiplets系统的方法。

  1. 现有开源模拟器用来模拟单个chiplet,通过多开[reuse]模拟器并行运行实现Multi-Chiplets。并提出模拟器间进程通信和同步协议[a full set of inter-simulator-process communication and synchronization protocol]来模拟chiplets之间的通信。
  2. 基于插入器的互连[Interposer-based interconnection]是使用特定参数精确建模的。互联可以通过仅网络方式[Network Only]系统调用仿真[SE]全系统仿真[FS]来模拟。可以容易的实现各种chiplet间和chiplet内的网络拓扑。
  3. 支持两种典型的内存模型:消息传递和共享内存
  4. 提出了一种基于文件的模拟器间进程通信和同步协议,使得多个模拟器进程同步运行,同理可集成其他模拟器。通过时序模型文件[Timing models files]和功能模型文件[Functional models files]支持远程存储器读写。这种通过进程的多开模拟器方法可以很好地实现并行模拟。

五、Multi-Chiplets系统仿真框架

此部分对应文章第三章

3.1 框架总览

  • 电路和物理层[Circuit and physical layer]:
  • 微体系结构和chiplet内部层 [micro-architectural and intra-chiplet layer]:每个单独的chiplet由一个模拟器进行模拟,模拟器还用于模拟路由器间的通道
  • chiplet间网络层[ inter-chiplet network layer]:该框架利用集中式网络管理器读取配置文件,以配置chiplet间的网络拓扑
  • 系统层[system layer]:通过功能模型文件和时序模型文件来实现共享内存模型和分布式内存模型。
    • 功能模型文件:远程读写请求写入每对模拟器进程的功能模型文件。
    • 时序模型文件:积累远程读写请求的延迟❓用来统计吗❓。
  • 应用层[Application layer]:该框架在应用层为程序员提供了用于远程读写的API,程序员可以借助此API开发测试程序。在gem5中的FS模式下,这个API使用m5 opt向主机生成时序模型文件和功能模型文件,用于模拟器之间的进程通信。在gem5的SE模式下,这个API系统调用处理程序向主机生成时序和功能模型文件,用于模拟器之间的进程通信。

3.2 远程读写协议

(1)远程读 Remote Read

远程读遵从握手协议,即Source Chiplet发送读取请求,Destination Chiplet回复

Source Chiplet有一个计时器,如果收到NACK或计时器超时未收到回复,则重新发送请求。其中,NACK用于模拟传输发生错误。

  • 在Destination Chiplet上,如果根据请求读取数据成功,则其接口节点,用ACK进行回复,它还可以通过回复NACK模拟传输错误

  • 其中,接口节点[Interface node]是每个Chiplet中负责Chiplet间通信的一个或多个节点

(2)远程写 Remote Write

远程写是非阻塞的。如果写入成功,则源Chiplet不受影响;若写入失败,则重新发送写请求。

存在一个缓冲区,用来保存未被确认的写入数据。

计算远程读请求的传输时间

为了计算远程读请求的传输时间[transmission time],Destination Chiplet的接口节点应该添加请求包从Source Chiplet发送过来的传输延迟;Source Chiplet一旦接收到回复,就计算此次请求的往返延迟(请求包和相应包的传输延迟)

全局内存一致性由软件管理。

尚未实现多芯片系统实现高速缓存/内存一致性协议。

死锁

在该系统中存在两种类型的死锁:

第一种是**路由级死锁[routing level deadlock],由数据包的循环依赖性引起。必须使用无死锁路由算法。第二种是协议级死锁[protocol level deadlock]**,由请求和应答数据包之间的依赖关系引起。

3.3 模拟器间进程通信和同步协议

模拟器间进程通信[inter-simulator-process communi-cation]使用两种类型的文件,即功能模型文件时序模型文件。每个模拟器为其他模拟器产生这两种类型的文件,并读取其他模拟器的这两种文件。

系统支持两种互联架构:**平铺式网络拓扑[tiled inter-chiplet network topologies]集中式网络拓扑[centralized inter-chiplet network topologies]**,在平铺式网络拓扑中,每个Chiplet有一个用于连接其他Cihplet的互连单元(AMD EPYC采用这样的网络架构)。在集中式网络拓扑中,有一个中心Chiplet,它连接这其他负责计算的Chiplet(AMD Ryzen采用了这样的架构)。

为了支持互联架构,提出了一种用来模拟中介层网络[ interposer-level network ]的网络管理器[ network manager ]

使用功能模型文件和时序模型文件进行远程读取的过程:

读请求

Chiplet i 通过API初始化了一个远程读Chiplet j 某个存储地址的请求。

  • Step 1:请求线程被stalled
  • Step 2:请求包首先被发送到接口节点
  • Step 3:接口节点分别生成功能模型文件$$F_{ik}$$和时序模型文件$$T_{iN}$$。其中,$$T_{iN}$$被发送到网络管理器;$$F_{ik}$$执行chiplet间路由。
  • Step 4:在到达模拟器k前把该请求包发送给模拟器j

开源仿真器说明书

摘自基于多芯粒集成的 X86 指令集共享式储存仿真器说明书

一、 简介

基于多芯粒集成 CPU 共享式储存仿真器是一款用于模拟多芯粒系统中 CPU 芯粒的仿真软件。它的主要功能是:模拟在 CPU 组成的多芯粒系统中,一个操作系统中某个或多个应用程序运行的过程,并给出运行结果以及各项性能指标,如程序的运行时间等。

二、gem5底层架构

三、仿真原理

每个chiplet 拥有自己独一无二的编号和自己的独特的共享储存区域,但是该储存区域可以被任何Chiplet读写。每个共享储存区域以 communication 开头表征,被所有 chiplet 共享。

当chiplet 需要从其他 chiplet 接收数据时,它会以自身 chiplet 编号对共享储存对应的区域进行检索,当检索到储存中有之前未读且停留在共享储存最久的数据时,它会将其读入自己的储存中,并标记该数据为已读。

1. 共享储存读操作

在功能模型上,读操作包括根据 chiplet 编号搜索储存,查找最久的未读数据以及标记本次读入的数据(若没有读入数据则跳过)。在 gem5 中,gadia_receive(a)函数执行读操作,a 表示本次要搜索的 chiplet 编号对应的储存。每次执行该函数时,gem5 将访问communicationa 文件,并读取该文件中最久没有被读取过内容读取完成之后将标记该数据已读并返回该数据,否则返回特定的数字(uint64_t)-1 的值。在时序模型上,读操作的时序由写操作的时序模型一起计算。

2. 共享储存写操作

在功能模型上,写操作包括根据 chiplet 的编号查找对应储存地址,写入数据。在gem5 中,gadia_call(a, b, c, d)函数执行写操作,其中 a 为当前 chiplet 编号,b 为数据将要传送的目标 chiplet 编号,c 为数据本身,d 为是否初始化共享储存。当 d 参数不要求初始化共享储存空间时,gem5 将访问文件 communicationb ,并在其内容追加内容 “gem5 当前 cycle a b c \n”。在时序模型上,每次写操作执行时,每个 chiplet 会自动检测当前的 cycle 数并将其一起写入共享储存,在仿真完成之后将交由 popnet 计算出共享储存的读写操作的延迟 cycle数。

四、仿真器工作流程

  • Step1 编写多机版本的负载程序,并编译成二进制文件。
  • Step2 挂载img镜像文件的方式将二进制负载程序放入img文件
  • Step3 启动多个gem5和m5
  • Step3 运行负载程序
  • Step4 编译附录A中的辅助程序,该程序统计共享储存的通信文件并输出 popnet 的输入文件,得到以 bench 开头的 trace 文件
  • Step5 以这些bench 开头的文件为输入,使用 popnet 计算片间通信。

popnet 是一款开源的互连网络模拟器,能够根据网络节点间的通信记录信息(trace 文件)计算出网络传递数据包的平均延迟以及总能耗。

五、仿真器使用具体步骤

1. 通过github或gitee下载仿真器源码

1
2
# Github
git clone https://github.com/FCAS-SCUT/chiplet_simulators

2. 构建X86环境

切换到gem目录下,然后构建环境,运行全系统模拟

这里使用三个线程并行地构建x86环境

1
scons ./build/X86/gem5.opt -j3

3. 编译测试程序

首先要构建libm5.a静态库

4. 挂载测试程序

benchmark目录下有三个文件夹

1
2
3
4
5
6
7
8
9
10
11
12
benchmark
- dependency
- gem5
- asm
- generic
- m5ops,h
- m5ops.h
- matrix
- test01.cpp
- treeSearching
- data.csv
- test01.cpp

其中,dependency文件夹包含了编译测试文件时需要的头文件,然后提供了matrix和treeSearching两个benchmark。

将parsec.img镜像文件挂载到mnt文件夹中

1
sudo mount -o loop,offset=1048576 disks/x86-parsec.img ./mnt

通过cp命令将benchmark二进制文件复制到mnt文件夹

取消挂载

1
sudo umount ./mnt

5.开启gem5

进入gem文件夹,开启gem5的FS模拟

启动模拟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
通过gem5提供的fs.py配置脚本进行快速配置,只需要通过命令行参数描述系统的配置。
如下,配置了一个八核、内存为256MB的模拟系统,且输出文件夹为checkpoint_parsec_1
./build/X86/gem5.opt \
-d core8/0 \
./configs/example/fs.py \
--kernel=x86-linux-kernel-4.19.83 \
--disk-image=x86-parsec.img \
--num-cpus=8 \
--mem-size=256MB


# fs.py
./build/RISCV/gem5.opt -d RISCVout/0 ./configs/example/fs.py --kernel=$M5_PATH/binaries/riscv-lupio-linux-kernel --disk-image=$M5_PATH/disks/riscv-ubuntu-20.04.img --num-cpus=4 --mem-size=256MB


# 命令行参数最少只需要指定vmlinux文件,img镜像文件
./build/X86/gem5.opt ./configs/example/fs.py --kernel=[vmlinux 二进制文件] --disk-image=[img 格式的系统镜像文件]

如果按以下操作把vmlinx和img文件所在的路径添加入环境变量,则可以直接输入文件名

1
2
3
4
5
6
添加环境变量
# 修改bashrc文件以添加环境变量
vim ~/.bashrc

# 在打开的文件的尾部加入环境变量
export M5_PATH=gem5绝对路径/full-system-image

6. 开启m5

然后在gem/util/term文件夹中通过m5term打开m5,使其通过命令行与模拟系统连接(首先你应该已经编译并安装了m5term)

1
m5term localhost <port>

然后就是漫长的等待,等待模拟系统的初始化

在模拟系统的命令行中通过m5 checkpoint创建检查点,然后再通过m5 exit退出模拟

通过检查点恢复模拟系统状态

1
2
3
4
5
6
7
8
./build/X86/gem5.opt \
-d core8/1 \
./configs/example/fs.py \
--kernel=x86-linux-kernel-4.19.83 \
--disk-image=x86-parsec.img \
--num-cpus=8 \
--mem-size=256MB
-r 1

./build/RISCV/gem5.opt -d RISCVout/0 ./configs/example/fs.py –kernel=$M5_PATH/binaries/riscv-lupio-linux-kernel –disk-image=$M5_PATH/disks/riscv-lupio-busybox.img –num-cpus=4 –mem-size=256MB –cpu-type=AtomicSimpleCPU