代码证据来源:
- gem5:本机
/home/hipper/ex_gem5_/gem5- Linux amdgpu 驱动:本机
/usr/src/amdgpu-6.3.6-1718217.22.04(AMD DKMS 版 KMD 6.3.6,对应 ROCm 6.3;上游内核路径为drivers/gpu/drm/amd/...)
1. gem5 AMDGPU 的 CP 建模现状:有"骨架",无"微架构"
1.1 已有的部分
| 组件 | 位置 | 说明 |
|---|---|---|
| PM4 包处理器 | src/dev/amdgpu/pm4_packet_processor.cc(约 1250 行) | 解析 PM4 包,但pm4_defines.hh只定义13 种 opcode(IT_NOP=0x10、IT_WRITE_DATA=0x37、IT_WAIT_REG_MEM=0x3C、IT_INDIRECT_BUFFER=0x3F、IT_RELEASE_MEM=0x49、IT_SET_UCONFIG_REG=0x79、IT_SWITCH_BUFFER=0x8B、IT_INVALIDATE_TLBS=0x98、IT_MAP_PROCESS=0xA1、IT_MAP_QUEUES=0xA2、IT_UNMAP_QUEUES=0xA3、IT_QUERY_STATUS=0xA4、IT_RUN_LIST=0xA5),是跑通 ROCm/KFD compute 路径的最小子集;真实硬件 PM4 有 60+ 种 |
| 队列描述符 | src/dev/amdgpu/pm4_queues.hh | HQD(hardware queue descriptor)结构体,直接取自 Linux 内核drivers/gpu/drm/amd/include/v9_structs.h |
| MMIO 寄存器 | src/dev/amdgpu/pm4_mmio.hh | 仅 70 行,doorbell、队列基址等寥寥几个 |
| HSA 层调度 | src/gpu-compute/gpu_command_processor.cc+src/dev/hsa/hw_scheduler.cc | 在 HSA/AQL 层面做队列唤醒(wakeup event)与 kernel dispatch,交给GPUDispatcher创建/分发 WG |
| SDMA | src/dev/amdgpu/sdma_engine.cc | 有独立的 SDMA 引擎模型 |
1.2 缺失的部分
- 没有 CP 微架构本体。真实 CP 是运行闭源固件(RLC/CP ucode/MES)的微控制器,有取指/译码/执行的 ring buffer 处理流水线——gem5 完全没有建模。PM4 包是 DMA 读入后功能级立即处理,无 CP 侧 cycle 时序。
- 没有 MES(Microcode Engine Scheduler)与多 compute ring 的硬件调度。
- 寄存器空间只有零头。真实 AMD GPU 有数万个 MMIO 寄存器,gem5 只实现了仿真 ROCm 所需的最小集合。
- 图形流水线完全没有(不支持 draw 类包)。
1.3 小结
gem5 这么做的原因:目标是跑通 ROCm 应用,瓶颈在 CU 执行,CP 只负责启动/收尾;且 CP 固件闭源,无法精确建模。想做"较为精细的 CP 建模",gem5 给不了现成的,但它是各选项中最适合自研扩展的底座——前提是把建模粒度定在"队列/包处理时序"而非"CP 固件执行"(后者因闭源在任何平台都做不到)。
2. 精细建模 CP 的三条路径
| 关注点 | 推荐路径 | 工作量 |
|---|---|---|
| chiplet 间 WG 分配/负载均衡/调度开销(多数 chiplet GPU 研究的实际切入点) | 扩展 gem5HWScheduler+GPUDispatcher,加 chiplet 感知队列调度与非对称 dispatch 延迟;Ruby/Garnet 可定制 xGMI/IF 拓扑 | 中 |
| CP 命令处理本身的时序(doorbell→ring→dispatch 延迟链) | 无现成开源模拟器。以 Linuxdrivers/gpu/drm/amd/amdgpu/为权威行为参考(gfx_v9_4_2.cring 管理、amdgpu_mes.c、寄存器头文件),自建时序层 | 大 |
| 嫌 gem5 太重 | MGPUSim(Akita 框架,Go,GCN3,原生多 GPU,模块化好);或 rocprofiler trace + 自写事件驱动仿真器 | 中/小 |
注意:gem5、MGPUSim、GPGPU-Sim 的 CP全部是功能级抽象,"CP 精细建模"目前是所有开源模拟器的空白——既是坑也是发论文的机会。
3. 参考资料:Chiplet / 多计算 die GPU 体系结构
3.1 学术奠基论文
| 工作 | 出处 | 内容 |
|---|---|---|
| MCM-GPU(Arunkumar, Bolotin, Milic, Ebrahimi, Villa, Jaleel, Wu, Nellans;NVIDIA Research) | ISCA 2017 | 领域开山之作。基于 GPGPU-Sim 3.x,系统论述 MCM-GPU 的 CTA 跨 die 调度、内存侧 L2 划分、页放置、die 间互连带宽敏感性。设计空间论述最完整的单篇,必读。注意其扩展代码据查未官方开源,后续研究者多自行重写 |
| Beyond the Socket: NUMA-aware GPUs(Milic et al.) | MICRO 2017 | 多 GPU/分区的 NUMA 效应,MCM-GPU 的姊妹篇 |
| Simba(Shao et al.,NVIDIA) | MICRO 2019 | 36-chiplet DL 推理芯片,实际流片。chiplet 粒度选择、NoP(network-on-package)、全局同步的论述最好。虽非 GPU,但"多计算 die 组织成一个大设备"的方法论通用 |
| Summarizing CPU and GPU Design Trends with Product Data(Yifan Sun et al.) | arXiv 2019 | 用产品数据(含 AMD/NVIDIA 多 die 演进)总结 GPU 趋势,背景调研好用 |
3.2 模拟器/开源项目
| 项目 | 说明 | 状态 |
|---|---|---|
| GPGPU-Sim 3.x / Accel-Sim | NVIDIA 执行模型;MCM-GPU 的母体 | 活跃 |
| MGPUSim + Akita(gitlab.com/akita/mgpusim) | Go、GCN3 ISA、原生多 GPU,做多 die 扩展最顺手 | MGPUSim 已归档(只读可用)/ Akita 维护中 |
| gem5 | 多 GPU 支持 + Ruby 可定制一致性 | 活跃 |
| BookSim / Garnet | 只建 die 间互连网络时配合用 | 活跃 |
3.3 商业架构参考(“真实 chiplet GPU 怎么做”)
- AMD MI250X (GFX90a):2 个 GCD,Frontier 超算;Hot Chips 34 (2022)。Linux
amdgpu驱动是研究其双 die 行为的最佳公开代码(见 §4)。 - AMD MI300A/X:XCD + CCD + IOD、3D 混合键合;Hot Chips 2023。chiplet 分工最激进。
- Intel Ponte Vecchio:47 tiles、Foveros/EMIB、Xe Link;Hot Chips 33 (2021) + IEEE Micro 文章。
- NVIDIA Blackwell B200:双 reticle die + NV-HBI(10 TB/s die-to-die);Hot Chips 2024。强调"两个 die 表现为单一统一 GPU"——与 CP/调度如何对上层隐藏多 die 直接相关。
- NVIDIA GRS(Ground-Referenced Signaling):Simba/Blackwell 背后的 die 间短距信号技术,JSSC/ISSCC 论文,互连功耗/带宽建模的依据。
3.4 与 CP 主题的交叉点
- 真正"跨计算 die 的 kernel/CTA 调度"研究,源头是MCM-GPU 的 CTA scheduler;后续多延续"GigaThread 引擎 die 感知化"路线。
- 没有任何公开工作精细建模"AMD CP 固件在 chiplet 间的行为"——空白地带。
- 检索关键词:
MCM-GPU、multi-chip-module GPU、chiplet GPU scheduling、die-to-die interconnect GPU、NUMA-aware GPU。
4. 案例详解:AMD MI250X 的 Linux amdgpu 驱动与双 die 行为
MI250X(代号Aldebaran,GFX90a,CDNA2)是一个封装内 2 个 GCD 的 chiplet GPU。内核驱动是理解"双 die 在系统软件眼中到底是什么"的最权威材料。以下全部基于本机 DKMS 源码(KMD 6.3.6)。
4.1 硬件组织:一个封装,两个独立 PCI 设备
关键事实:MI250X 的两个 die 不作为统一设备暴露,而是两个独立的 PCI 设备,各自有独立 BDF、BAR、amdgpu_device实例。驱动 PCI ID 表(amd/amdgpu/amdgpu_drv.c:2029-2032):
{0x1002,0x7408,PCI_ANY_ID,PCI_ANY_ID,0,0,CHIP_ALDEBARAN},{0x1002,0x740C,PCI_ANY_ID,PCI_ANY_ID,0,0,CHIP_ALDEBARAN},{0x1002,0x740F,PCI_ANY_ID,PCI_ANY_ID,0,0,CHIP_ALDEBARAN},{0x1002,0x7410,PCI_ANY_ID,PCI_ANY_ID,0,0,CHIP_ALDEBARAN},(4 个 DID 对应 MI210/MI250/MI250X 等 SKU。)每个 die probe 出一个完整的amdgpu_device,有独立的 CP、ring、KFD 队列、HBM 段。双 die 之间的纽带不是"一个设备内部",而是内核的 xGMI hive 抽象——从驱动结构看,chiplet GPU(MI250X 风格)在调度语义上等价于多 GPU。
4.2 xGMI Hive:内核中的多 die 抽象
struct amdgpu_xgmi(amd/amdgpu/amdgpu_gmc.h:168):
structamdgpu_xgmi{/* from psp */u64 node_id;u64 hive_id;/* fixed per family */u64 node_segment_size;/* physical node (0-3) */unsignedphysical_node_id;/* number of nodes (0-4) */unsignednum_physical_nodes;/* gpu list in the same hive */structlist_headhead;bool supported;structras_common_if*ras_if;bool connected_to_cpu;/* Frontier 形态:经一致性 xGMI 连 CPU */bool pending_reset;structamdgpu_xgmi_ras*ras;};Hive 组建流程(amdgpu_xgmi.c: amdgpu_xgmi_add_device()):
- 驱动通过PSP 固件(Platform Security Processor)完成链路层工作:
psp_xgmi_initialize()→psp_xgmi_get_hive_id()→psp_xgmi_get_node_id()。xGMI 链路训练/拓扑发现不在内核而在固件,内核只是查询。 - 同 hive_id 的设备挂入共享的
amdgpu_hive_info(含device_list、hive_lock、任务 barrier)。 - 每加入一个 die,调用
amdgpu_xgmi_update_topology()并用psp_xgmi_get_topology_info()向所有成员同步最新拓扑(全互联视图表)。 - die 间距离以跳数表示:
amdgpu_xgmi_get_hops_count()从 PSP 拓扑表读num_hops(amdgpu_xgmi.c:737起)。
用户态可见:/sys/.../xgmi_node_id、xgmi_physical_node_id(amdgpu_xgmi.c:377/388)。
4.3 统一物理地址空间:node segment 分段
双 die 间 P2P 内存访问的实现核心,在 GMC 初始化(amd/amdgpu/amdgpu_gmc.c:248-250):
u64 hive_vram_end=mc->xgmi.node_segment_size*mc->xgmi.num_physical_nodes-1;mc->vram_start=mc->xgmi.node_segment_size*mc->xgmi.physical_node_id;mc->vram_end=mc->vram_start+mc->xgmi.node_segment_size-1;- 整个 hive 是一个统一物理地址空间:
node_segment_size × num_physical_nodes;每个 die 占其中一段,段基址 =physical_node_id × node_segment_size。 - 跨 die 访问 = 页表项直接编码全局地址,由 XGMI fabric 按地址段路由到目标 die(“far memory”)。
amdgpu_xgmi_get_relative_phy_addr()(amdgpu_xgmi.c:973)即addr + physical_node_id * node_segment_size。 physical_node_id与seg_size由 firmware 预配置在MC_VM_XGMI_LFB_CNTL寄存器(PF_LFB_REGION字段等),驱动在gfxhub_v1_2.c:600-615读取——硬件告诉软件"我是 hive 里的第几个 die、每段多大"。- MI250X 每 die 64GB HBM2e(4 stack),hive 全局 VRAM 视图 128GB。
建模要点:这套"地址段 + fabric 路由"机制与 gem5 的多 GPU 地址映射/ Ruby 目录完全可以对应,是实现 MI250X 风格双 die 的最小机制。
4.4 KFD 拓扑:双 die 如何暴露给用户态
- 每个 die 是一个独立KFD node(
/sys/class/kfd/kfd/topology/nodes/<n>),kfd_device.c:760:kfd->hive_id = kfd->adev->gmc.xgmi.hive_id。 - die 间链路写进CRAT表:
kfd_fill_gpu_xgmi_link_to_gpu()(kfd_crat.c:1994),类型CRAT_IOLINK_TYPE_XGMI;链路权重用iolink->weight_xgmi(kfd_crat.c:1167-1168),跳数来自 §4.2 的 PSP 拓扑。 - 用户态(ROCr/HIP)据此做 NUMA 式放置:选择 agent(die)→ 在该 die 上建队列 → 分配内存时按链路 weight/hops 决定本地或远端。
- SVM(统一虚拟内存)中跨 die 共享以
amdgpu_xgmi_same_hive()判断可行性(kfd_svm.c:1204)。
4.5 CP/队列:每 die 独立,无跨 die 硬件调度
这是对 chiplet CP 建模最重要的一节:
- 每个 die 有完整的独立 CP 复合体:GFX ring + compute rings(MEC/HWS 每 die 一套)。
gfx_v9_4_2.c(GC 9.4.2 = Aldebaran 专有初始化)中可见驱动直接用adev->gfx.compute_ring[0]、[1]提交 golden SGPR/VGPR 初始化 compute shader(gfx_v9_4_2_do_sgprs_init()等),ring 全部是 per-device(= per-die)资源。 - 不存在硬件级跨 die workgroup 分发:一个队列固定属于一个 die 的 HQD;跨 die 的负载划分完全由软件完成——应用用 HIP multi-device 显式在两个 device 上各建 stream/queue,或靠运行时按拓扑拆分。
- die 间数据共享靠 §4.3 的统一地址 + P2P,一致性由 fabric 硬件维护,对 CP 透明。
结论:MI250X 的"chiplet"性体现在内存/一致性/拓扑层,而不在 CP/调度层。用模拟器复现 MI250X 行为,不需要任何 CP 微架构创新——两个独立 GPU 节点 + xGMI 段式地址空间 + hive 拓扑即可。真正需要 CP/dispatcher 创新的,是 MI300 那种统一设备形态(§4.7)。
4.6 GPU Reset 的 hive 协同
aldebaran.c(427 行)基本全部围绕一件事:XGMI hive 中多节点的 mode2 reset 协同:
aldebaran_mode2_perform_reset():hive 内所有节点并行发 reset(For XGMI run all resets in parallel to speed up the process),再统一等待完成(amdgpu_xgmi的 task barrier 同步)。- 恢复后
amdgpu_xgmi_update_topology()重建 hive 拓扑。 connected_to_cpu(Frontier 形态:MI250X 经一致性 xGMI 连 Trento EPYC)决定默认 reset 方式(aldebaran_is_mode2_default())。
说明 chiplet GPU 的 RAS/reset 也是 hive 级问题,建模时若关注可靠性场景需考虑。
4.7 MI250X vs MI300:软件显式 vs 硬件统一
驱动里能直接看到两种 chiplet GPU 哲学的差异:
| MI250X(GFX90a / GC 9.4.2) | MI300(GFX942 / GC 9.4.3) | |
|---|---|---|
| 设备形态 | 每 die 一个 PCI 设备、一个amdgpu_device | 单 PCI 设备,内部多 XCC(Accelerated Compute Core,即 XCD 复合体) |
| 多 die 寻址 | 多设备 + xGMI hive 段式地址 | 单设备内xcc_id实例选择:RREG32_XCC(reg, inst)/WREG32_XCC(...)(amdgpu.h:1265-1266),aid_mask(amdgpu.h:1140)枚举实例 |
| 跨 die 调度 | 无硬件支持,软件显式(HIP multi-device) | 硬件/固件将多 XCD 呈现为统一计算设备,dispatcher 层做 die 间 WG 分配 |
| 建模含义 | 多 GPU 模型 + 互连即可 | 必须建 chiplet 感知的 CP/dispatcher:队列如何拆分、WG 如何落到不同 XCD、die 间缓存一致性对 dispatch 延迟的影响 |
4.8 对 chiplet GPU 建模的启示
- 先选定要建哪种 chiplet GPU:MI250X 式(软件显式多设备)还是 MI300 式(硬件统一设备)。前者用现成模拟器拼多 GPU + 定制互连即可;后者才是"需要扩展 CP/调度建模"的场景。
- 驱动是行为规范的金标准:hive 组建、段式地址、CRAT 拓扑、reset 协同在
amdgpu源码中全部可读,且比任何论文都精确。建模 MI250X 风格时,§4.2–4.6 的机制清单可直接当作"要实现的最小功能集"。 - CP 精细建模的合理落点:对统一设备形态,落点在dispatcher 的 die 感知 + 非对称 dispatch 时延 + die 间一致性流量,而不是 CP 固件执行(闭源,无据可依)。
5. 总结
- gem5 AMDGPU 的 CP 只有功能级骨架(13 种 PM4 opcode、70 行 MMIO),无 CP 微架构——直接用于精细 CP 建模不可行,但作为扩展底座可行。
- 若目标是 MI250X 式 chiplet GPU:驱动分析表明其双 die 在调度语义上就是多 GPU,无需 CP 创新,重点建 xGMI 段式地址 + hive 拓扑 + die 间 NUMA。
- 若目标是 MI300 式统一设备:需要自研 chiplet 感知 dispatcher(gem5
HWScheduler/GPUDispatcher扩展,或 MGPUSim/Akita),以 Linuxamdgpu源码为行为参照。 - 领域空白:AMD CP 固件级建模无人可做(闭源);队列/包处理时序 + die 感知调度的中间粒度,是可行且有发表空间的位置。