推广 热搜: 采购方式  滤芯  带式称重给煤机  甲带  气动隔膜泵  减速机型号  无级变速机  链式给煤机  履带  减速机 

XNACK/ATS 技术白皮书:AMD GPU 可恢复缺页机制的软硬件架构与实现

   日期:2026-08-09 22:54:48     来源:网络整理    作者:本站编辑    评论:0    
XNACK/ATS 技术白皮书:AMD GPU 可恢复缺页机制的软硬件架构与实现

摘要

XNACK(eXception on Negative ACKnowledgement)是 AMD GPU 架构中支持"可恢复内存访问缺页"(Recoverable Memory Page Fault)的核心机制,是实现统一内存(Unified Memory / SVM,Shared Virtual Memory)的关键基础设施。它使得 GPU wavefront 在访问尚未驻留的虚拟地址时能够挂起等待、由驱动完成缺页处理后重放(replay)访存,而非直接触发致命错误。本文从硬件流水线、内存管理单元设计、内核驱动(amdgpu/KFD)到用户态运行时(ROCm/HSA)四个层次,系统梳理 XNACK 的软硬件协同架构与实现路径。


1. 背景与动机

1.1 传统 GPU 内存模型的局限

传统离散 GPU 编程模型要求应用显式管理设备内存:hipMalloc/cudaMalloc 分配的内存必须提前 pin 并建立页表映射,访问未映射地址直接导致 VM_FAULT(致命异常),kernel 被杀死。这种模型对以下场景不友好:

  • • 大规模不规则数据结构(图计算、稀疏矩阵)的按需迁移
  • • CPU/GPU 之间细粒度共享同一虚拟地址空间(如 hipMallocManaged)
  • • Oversubscription:working set 超过显存容量时的透明分页

1.2 XNACK 的角色定位

XNACK 本质上是 GPU 硬件对"缺页可恢复"的协议级支持:当访存单元(TA/TC,或更底层的 L1/L2 cache 控制器)检测到地址转换失败时,硬件不是立即 fault-kill,而是:

  1. 1. 向发起该访存的 wave 返回一个 NACK(negative acknowledgement)
  2. 2. wave 因此进入 stall/sleep 状态,指令不退休
  3. 3. 硬件生成一次 retry-able page fault 上报给内核驱动
  4. 4. 驱动完成缺页处理(分配物理页、建立映射、必要时页迁移)后更新页表
  5. 5. 硬件将该访存请求 replay(重放),wave 恢复执行

这与 x86 CPU 缺页中断的语义高度相似,区别在于 GPU 是大规模 SIMT 并行执行,需要在 wavefront 粒度上处理"部分 lane 命中、部分 lane 缺页"的复杂情形,且缺页处理延迟(微秒到毫秒级)远高于 CPU(因为常伴随跨 PCIe/xGMI 的页迁移)。


2. 硬件架构

2.1 地址转换路径

GPU 的虚拟地址转换涉及多级结构:

Miss
Miss
PTE Valid
PTE Invalid 或
ATC miss
Wavefront 发起 Load/Store
L1 TLB / uTLB
L2 TLB / GPU MMU
Page Table Walker
GPUVM 页表
Radix-tree, VMID索引
返回物理地址/系统地址
生成 Retry Fault
VM Fault FIFO
写入 IH Ring
中断上报 amdgpu IH -> KFD

关键结构:

  • • GPUVM(GPU Virtual Memory):多级 radix 页表,以 VMID 区分不同进程/上下文的地址空间,与 amdgpu 的 amdgpu_vm 软件对象一一对应。
  • • ATC(Address Translation Cache):位于 XGMI/IOMMU 路径上,用于缓存 GPU 侧对系统内存(CPU 侧 page table,通过 IOMMUv2/ATS 获取)的翻译结果。
  • • VM Fault FIFO / Interrupt Handler Ring:硬件将 fault 信息(faulting VMID、地址、读写属性、client id)打包写入中断队列,供驱动异步消费。

2.2 XNACK 使能与 wave 的行为差异

XNACK 是否使能,直接决定硬件对缺页的处理策略,这是理解该机制的核心:


       
         
           
           
         
状态硬件行为软件语义
XNACK OFF缺页立即视为致命错误,触发 VM_FAULT 中断并可能导致该 VMID 下所有 wave 被杀死传统模型:内存必须提前完全映射(如 hipMalloc/pinned memory)
XNACK ON缺页时硬件向发起 wave 返回 NACK,wave 挂起等待重放;同时上报 retry fault 给驱动SVM/托管内存模型:允许按需分页、迁移、hipMallocManaged
       

     

在 CDNA(MI100/MI200/MI300 系列)架构上,XNACK 通过 GPU firmware/固件配置位控制,且同一进程运行期间不可切换——这是因为 wave 的缺页恢复路径(compute unit 内部的 replay 缓冲)在两种模式下微架构行为不同,切换需要重新加载 kernel context。这也是 ROCm 中 HSA_XNACK 环境变量必须在进程启动前设置的硬件根因。

2.3 Retry Fault 的硬件字段

一次典型的 GPU retry page fault 中断携带的信息包括:

  • • Faulting page address(触发缺页的虚拟地址,按 page 粒度对齐)
  • • VMID:标识发起访问的进程上下文
  • • Client ID / Engine ID:区分是 Compute Unit(CU)发起,还是 SDMA、显示引擎、CP 等其他硬件模块
  • • 访存类型:Read / Write / Execute / Atomic(Atomic 缺页处理更复杂,因为需要保证 read-modify-write 的原子语义在 replay 后仍成立)
  • • Timestamp

多个 CU 并发触发的 fault 会在 fault FIFO 中排队,硬件保证同一地址的多次 fault 不会无限重复上报(有去重/合并机制,通常以 fault 地址+VMID 为 key)。

2.4 与 IOMMU/ATS/PRI 的协同(APU 场景)

在 APU(如 MI300A)或启用了 HSA 完全一致性内存模型的平台上,GPU 缺页处理会与 CPU IOMMU 的 ATS(Address Translation Service) 和 PRI(Page Request Interface,PCIe 定义的标准协议) 协同:

amdgpu/KFD DriverCPU Page TableIOMMU(AMD-Vi)/ATCGPU CU/uTLBamdgpu/KFD DriverCPU Page TableIOMMU(AMD-Vi)/ATCGPU CU/uTLBATS 翻译请求MissPRI Page Request上报 IOMMU page fault触发 mmu_notifier / get_user_pages物理页就绪PRI Response (Success)ATS Invalidate + 重新翻译成功Wave Replay

这一路径使得 GPU 可以直接缺页式访问 CPU 侧 malloc 分配的匿名内存,而无需显式 hipHostRegister。


3. 软件架构

3.1 分层视图

硬件
内核态
用户态
ioctl SVM_OPS
更新页表
retry fault 中断
dispatch
HIP/OpenCL 应用
HSA Runtime / ROCr
HIP Runtime
KFD (Kernel Fusion Driver)
amdgpu_amdkfd_*
KFD SVM 模块
kfd_svm.c / svm_range
amdgpu DRM Driver
VM 管理 / IH 处理
mmu_notifier / HMM
hmm_range_fault
TTM 内存管理器
BO 迁移
Interrupt Handler Ring
GMC/GPUVM 页表引擎

3.2 关键内核数据结构

svm_range:KFD SVM 子系统中管理一段可能被缺页/迁移的虚拟地址区间的核心结构(drivers/gpu/drm/amd/amdkfd/kfd_svm.h),记录:

  • • 起止虚拟地址、所属 mm_struct
  • • 当前 actual location(驻留在系统内存还是某块 GPU 显存,prange->actual_loc)
  • • prefetch/迁移策略提示
  • • 关联的 mmu_interval_notifier,用于响应 CPU 侧地址空间变化(如 munmap、fork 后的 COW)

svm_range_list:每个 kfd_process 一份,以 interval tree 组织所有 svm_range,支持按地址快速查找覆盖范围。

Retry Fault 处理入口(简化后的逻辑路径,对应 svm_range_restore_pages):

// 伪代码,示意 KFD 处理 GPU retry fault 的核心流程
int
 svm_range_restore_pages(struct kfd_node *node,
                             unsigned
 int pasid,
                             uint64_t
 addr, bool write_fault)

{
    struct kfd_process *p =
 kfd_lookup_process_by_pasid(pasid);
    struct svm_range *prange =
 svm_range_from_addr(&p->svms, addr);

    /* 1. 依据 prange 决定迁移策略:
     *    - 若目标应驻留 GPU 显存 -> migrate_vma_* 迁移
     *    - 若应驻留系统内存 -> hmm_range_fault 直接取得 PFN */

    if
 (prange->preferred_loc == node->id)
        svm_migrate_to_vram(prange, node, addr);
    else

        hmm_range_fault(&hmm_range); /* 走 HMM 通用路径 */

    /* 2. 更新 GPUVM 页表 (PTE),指向新物理页 */

    svm_range_map_to_gpu(node, prange, addr);

    /* 3. 通知硬件 replay:写 fault-done 到 GMC/IH */

    amdgpu_gmc_fault_recovery(node->adev, pasid, addr);

    return
 0;
}

3.3 与 Linux HMM 框架的集成

XNACK/SVM 软件栈重度依赖内核的 HMM(Heterogeneous Memory Management) 基础设施:

  • • hmm_range_fault():驱动通过该接口,以非阻塞方式取得给定虚拟地址范围当前对应的 PFN(若尚未在 CPU 侧建立映射,会触发标准 CPU 缺页处理链路)。
  • • mmu_interval_notifier:注册在目标地址区间上,一旦 CPU 侧发生 TLB 失效(如页面被换出、迁移、COW),驱动会收到回调并使 GPU 侧对应的 PTE 失效,保证一致性。
  • • migrate_vma_setup/migrate_vma_pages/migrate_vma_finalize:这一组接口用于把系统内存页迁移为设备私有页(Device Private Memory,MEMORY_DEVICE_PRIVATE),是 XNACK 场景下"数据靠近计算"(migrate-on-fault)策略的底层实现,GPU 显存以 ZONE_DEVICE 的形式纳入内核内存管理框架。
否, 系统内存
是,已迁移到本GPU
是,在其他GPU上
GPU Retry Fault: addr X
prange 查找
hmm_range_fault
PFN 是否为
DEVICE_PRIVATE?
直接建立 GPU PTE 指向该 PFN
migrate_vma 迁移到本GPU显存
amdgpu_gmc_fault_recovery
触发硬件 replay

3.4 与用户态 ROCm 栈的接口

  • • HSA Runtime(ROCr):hsa_amd_memory_pool_allocate 配合 HSA_AMD_MEMORY_POOL_STANDARD_FLAG 或直接使用系统 malloc + hsa_amd_svm_attributes_set,向内核声明该内存区域参与 SVM。
  • • hipMallocManaged / hipMemAdvise / hipMemPrefetchAsync:HIP 层面对 CUDA UM API 的对齐实现,底层最终转化为对 KFD ioctl(AMDKFD_IOC_SVM) 的调用,设置 prange 的 preferred location、prefetch 提示等属性,直接影响 3.3 节中迁移决策的选择。
  • • 环境变量 HSA_XNACK=1:这是用户态触发内核为该进程建立"可恢复缺页"上下文的开关,本质上是在进程创建 KFD context 时向硬件请求以 XNACK-enabled 模式初始化该 VMID 的 fault 处理策略。

4. 端到端流程整合

HMM/mmu_notifierKFD SVM中断处理GPUVM/GMC硬件GPU Compute Unit应用 (hipMallocManaged 内存)HMM/mmu_notifierKFD SVM中断处理GPUVM/GMC硬件GPU Compute Unit应用 (hipMallocManaged 内存)Wave 挂起 (不退休指令)Wave 恢复执行Kernel 访问未驻留地址 X发起 LoadPTE Invalid -> NACK上报 Retry Page Fault(X, VMID, RW)中断 -> 加入 fault 处理队列hmm_range_fault / migrate_vma物理页就绪 (PFN)更新 PTE(X) 有效触发 fault recovery / TLB invalidateReplay 信号重新发起 Load(X)Hit,正常返回数据

需要强调几个实现细节上的复杂性:

  1. 1. Wavefront 部分缺页:一个 wave 的 64 个 lane 可能只有部分 lane 命中缺页地址,硬件需要按 lane mask 记录哪些 lane 需要 replay,避免已完成的 lane 被重复执行(这对访存有副作用的场景,如 atomic,尤为关键)。
  2. 2. Fault 风暴与 QoS:大规模并发缺页(如冷启动大数据集的图算法)可能产生海量 fault 中断,驱动需要合并/限流处理,否则中断处理开销会反噬性能——这也是为何 hipMemPrefetchAsync 这类"主动预取"API 在实践中比纯粹依赖缺页驱动的迁移性能更优。
  3. 3. Livelock 防护:迁移过程中若目标页再次被其他 wave 或 CPU 线程并发访问导致状态变化,驱动需要保证 fault 处理的最终收敛,避免"迁移-替换-再缺页"的无限循环。

5. 性能与工程考量

  • • 延迟量级:GPU retry fault 从触发到 replay 完成,典型延迟在数微秒(命中系统内存、无需迁移)到数百微秒甚至毫秒级(需要跨 xGMI/PCIe 迁移大页)不等,相比 L2 TLB miss 的几十纳秒有数量级差距,因此 XNACK 模式下的 kernel 若 working set 局部性差,性能会显著劣化。
  • • XNACK 对寄存器分配的影响:在 CDNA 架构上,开启 XNACK 会占用额外的硬件资源用于保存 replay 所需的上下文(部分文献/AMD 文档提及会影响可用 VGPR 数量或 occupancy),这是"按需选择是否开启 XNACK"而非默认全局开启的现实工程原因之一。
  • • 与显式内存管理的权衡:生产环境的高性能 HPC/AI workload 通常仍偏好显式 hipMalloc + 手动 hipMemcpyAsync,将 XNACK/SVM 用于原型开发、不规则数据结构或内存超订阅场景,二者并非互斥,可在同一应用中混合使用。

6. 总结

XNACK 机制体现了现代 GPU 从"纯加速器"向"一等公民的可编程处理器"演进过程中,在硬件缺页语义、内核异构内存管理(HMM)与用户态运行时(ROCm/HSA)三层之间构建的协同设计。其硬件基础是 NACK-replay 式的缺页恢复流水线与 GPUVM/ATC 地址转换体系,其软件核心是 KFD SVM 子系统对 Linux HMM 框架的深度集成,最终对上层暴露为 hipMallocManaged 等统一内存编程模型。理解这一机制,对于诊断 ROCm 应用中的缺页性能问题、设计跨 CPU/GPU 的内存迁移策略,以及评估 UM/SVM 模型与显式内存管理的取舍,都具有直接的工程意义。

 
打赏
 
更多>同类资讯
0 条相关评论

推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  皖ICP备20008329号-18
Powered By DESTOON