news 2026/6/24 20:02:35

Pascal GPU 如何从“零”开始获取页表项

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Pascal GPU 如何从“零”开始获取页表项

Pascal GPU 如何从“零”开始获取页表项的完整链条,涵盖页表的生成、结构、存储以及 GPU 硬件遍历页表的具体步骤:


1. 页表的生成与生命周期 (软件层:操作系统 & NVIDIA UVM 驱动)

  • 责任方:主机 CPU 上的操作系统 (OS)NVIDIA Unified Virtual Memory (UVM) 驱动
  • 核心目标:每个进程维护一个多级页表结构,将进程的虚拟地址 (VA)映射到物理地址 (PA)。这个页表是系统全局的,CPU 和 GPU (通过 UVM)共享同一套映射。
  • 生成过程:
    1. 进程创建:当应用程序进程启动时,OS 内核为其分配一个顶级页目录 (Page Global Directory, PGD)物理页框 (Page Frame)。在 x86-64 上,PGD 的基址存储在 CPU 的CR3寄存器中(进程上下文的一部分)。
    2. 内存分配:当进程通过malloc()mmap()等系统调用分配内存时:
      • OS 内核在进程的 VA 空间分配一段虚拟地址范围。
      • OS 为这段 VA 分配物理页框(可能来自物理内存池,或触发缺页中断从磁盘加载)。
      • OS遍历或创建进程的多级页表结构(PGD -> PUD -> PMD -> PT),在最终级的页表 (Page Table, PT)中设置对应的页表项 (Page Table Entry, PTE)
      • PTE 关键内容:
        • Present Bit:1 表示物理页存在且映射有效。
        • 物理页框号 (Page Frame Number, PFN):指向目标物理页的基址。
        • 权限位 (RWX):读/写/执行权限。
        • 其他标志位:如 Dirty, Accessed, User/Supervisor 等。
    3. UVM 驱动的介入:
      • UVM 驱动作为内核模块,拦截OS 的内存管理操作(特别是与 GPU 共享内存相关的部分)。
      • 驱动确保为 GPU 可访问的内存分配的物理页框位于 GPU 能直接访问的物理地址范围内(例如,通过cudaMallocManaged分配的统一内存)。
      • 驱动维护一个特殊的进程上下文结构,其中包含该进程的CR3值(即 PGD 的 HPA)以及其他 GPU MMU 所需的状态信息。
      • 当 GPU 需要为该进程执行计算时,UVM 驱动会将这个进程上下文(包含CR3加载到 GPU 的特定 MMU 上下文寄存器中(通常通过写 GPU 的 MMIO 空间实现)。

2. 页表在主机内存中的结构 (硬件视角)

  • 存储位置:页表的所有级别(PGD, PUD, PMD, PT)都存储在主机 (CPU) 的物理内存 (DRAM)中。
  • 物理地址:页表本身也占据物理内存页框,因此每个页表项(无论是 PGD 项、PUD 项、PMD 项还是 PTE 项)都有一个唯一的主机物理地址 (Host Physical Address, HPA)
  • 多级结构 (以 x86-64 4级页表为例):
    • PGD (Page Global Directory):顶级目录。一个进程一个 PGD。CR3寄存器存储其 HPA。
    • PUD (Page Upper Directory):第二级目录。一个 PGD 项指向一个 PUD。
    • PMD (Page Middle Directory):第三级目录。一个 PUD 项指向一个 PMD。
    • PT (Page Table):第四级目录。一个 PMD 项指向一个 PT。一个 PT 包含 512 个 PTE (假设 4KB 页)。
    • PTE (Page Table Entry):最终项,包含目标物理页框的 PFN 和标志位。
  • 页表项格式:Pascal GPU 的 MMU 硬件被设计为理解 CPU 架构(如 x86-64 或 ARMv8)定义的页表项格式。例如,一个 x86-64 PTE 是 64 位宽,包含 PFN、Present、RW、User/Supervisor、Accessed、Dirty 等位。GPU 硬件知道如何解析这些位来获取下一级页表的 HPA 或最终的物理页 PFN。

Host Physical Memory

Entry 0

Entry 1

...

Entry 0

Entry 1

Entry 0

Entry 1

Entry 0

Entry 1

PGD Base HPA CR3

PUD Table HPA

PUD Table HPA

...

PMD Table HPA

PMD Table HPA

PT Table HPA

PT Table HPA

PTE: PFN + Flags

PTE: PFN + Flags


3. GPU 硬件如何“拿”页表项 (Pascal PWT 的遍历流程)

这是最关键的部分!当 GPU SM 请求一个 VA 翻译,但 TLB 和 PTC 都未命中时,Page Walk Engine (PWT)接管:

  1. 获取起点:PGD 基址 HPA (CR3):

    • PWT 从当前加载的 MMU 上下文寄存器中读取CR3值。这个值是 UVM 驱动在调度该 GPU 进程时写入的,是PGD 表的起始 HPA
    • CR3是遍历的绝对起点!
  2. 计算 PGD 索引:

    • PWT 硬件根据VA (Virtual Address)的特定位域(在 x86-64 中通常是VA[47:39])计算出在 PGD 表中的索引 (Index)
    • 目标 PGD 项的 HPA = PGD Base HPA (CR3) + Index * sizeof(PGD_Entry)
  3. 发起 MRd TLP 获取 PGD 项:

    • PWT 生成一个PCIe Memory Read (MRd) TLP请求。
    • 请求地址 (Address):上一步计算出的目标 PGD 项的 HPA
    • 请求长度 (Length):通常是一个完整的缓存行(如 64 字节),可能包含多个相邻的 PGD 项(预取优化)。
    • 该 TLP 通过 PCIe 总线发送到主机。
    • (可选 IOMMU 步骤):如果系统启用了 IOMMU/SMMU,这个 HPA 会被当作 IOVA 处理,由 IOMMU 翻译成真正的 SPA 后再访问主机内存。
    • 主机内存响应:主机内存控制器读取该 HPA (或 SPA) 处的数据(即包含目标 PGD 项在内的缓存行数据),封装成Completion with Data (CplD) TLP返回给 GPU。
  4. 解析 PGD 项,获取 PUD 基址 HPA:

    • GPU PWT 硬件接收到返回的数据。
    • 它从数据中提取出目标PGD 项
    • 解析 PGD 项:
      • 检查 Present 位:如果为 0,触发 Page Fault 上报驱动。
      • 如果有效,从 PGD 项中提取出下一级页表 (PUD) 的基址 HPA。这个 HPA 指向一个完整的 PUD 表所在的物理页框。
  5. 计算 PUD 索引:

    • 根据 VA 的下一个位域(如VA[38:30])计算在 PUD 表中的索引
    • 目标 PUD 项的 HPA = PUD Base HPA (从 PGD 项来) + Index * sizeof(PUD_Entry)
  6. 发起 MRd TLP 获取 PUD 项:

    • 重复步骤 3:生成 MRd TLP,请求地址为目标 PUD 项的 HPA,获取包含该 PUD 项的数据。
  7. 解析 PUD 项,获取 PMD 基址 HPA:

    • 解析返回的 PUD 项,检查有效位,提取出PMD 表的基址 HPA
  8. 计算 PMD 索引:

    • 根据 VA 的位域(如VA[29:21])计算在 PMD 表中的索引。
    • 目标 PMD 项的 HPA = PMD Base HPA + Index * sizeof(PMD_Entry)
  9. 发起 MRd TLP 获取 PMD 项:

    • 获取目标 PMD 项。
  10. 解析 PMD 项,获取 PT 基址 HPA:

    • 解析 PMD 项,提取出PT (Page Table) 的基址 HPA
  11. 计算 PT 索引:

    • 根据 VA 的位域(如VA[20:12])计算在 PT 表中的索引。
    • 目标 PTE 的 HPA = PT Base HPA + Index * sizeof(PTE)
  12. 发起 MRd TLP 获取 PTE:

    • 获取目标PTE (Page Table Entry)
  13. 解析最终 PTE:

    • PWT 解析返回的 PTE:
      • 检查 Present 位:如果为 0,触发 Page Fault 上报驱动。
      • 检查权限位:如果 GPU 请求的访问类型(读/写)超出权限,触发 Permission Fault。
      • 如果有效且权限足够,从 PTE 中提取出目标物理页框的 PFN (Page Frame Number)
    • 最终物理地址 (PA) = (PFN << PAGE_SHIFT) + VA 的页内偏移 (VA[11:0])
  14. 更新缓存 & 完成请求:

    • 将最终有效的 PTE 加载到TLB (L1/L2)中。
    • 将遍历过程中获取到的中间页表项 (PGD, PUD, PMD)和 PTE 缓存到Page Table Cache (PTC)中,加速未来对相同或邻近 VA 的访问。
    • 将最终得到的 PA 提供给最初发起请求的 SM,使其能够访问物理内存。

关键点总结:Pascal 如何“拿”页表

  1. 软件奠基:OS 和 UVM 驱动在主机内存中创建和维护标准的多级页表结构,并将进程的顶级目录基址 (CR3 HPA)告知 GPU。
  2. 硬件遍历:GPU 的Page Walk Engine (PWT)是执行遍历的专用硬件
  3. 按级索骥:PWT 严格按照 CPU 定义的页表结构和VA 位域划分,逐级计算索引:
    • PGD Index -> PUD Index -> PMD Index -> PT Index
  4. 地址计算:每一级目标项的 HPA 都是:
    • 当前级基址 HPA (来自寄存器或上一级项) + 当前级索引 * 项大小
  5. PCIe 获取:每一级缺失项的 HPA 都被用来发起标准的 PCIe Memory Read (MRd)事务,从主机物理内存中读取该项(通常附带一个缓存行)。
  6. 硬件解析:GPU 硬件理解 CPU 页表项格式,解析每一级返回的项,提取出下一级基址 HPA或最终物理页框号 (PFN)
  7. 缓存优化:获取到的页表项(包括中间项和 PTE)被缓存在 GPU 本地的PTCTLB中,极大减少后续遍历需求。
  8. 故障处理:遍历过程中遇到的无效项或权限错误会触发页故障中断,由 UVM 驱动处理。

整个过程的核心是:GPU 硬件利用驱动提供的起始点 (CR3 HPA),结合对 VA 的位域解析和对标准页表项格式的理解,像“爬梯子”一样,通过发起一系列 PCIe 内存读请求,逐级获取主机内存中的页表项,最终找到目标物理地址。Pascal 的专用 PWT 硬件和 PTC 缓存使这个过程高效且对 SM 计算单元透明。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/21 14:51:44

救命神器!专科生必看10款一键生成论文工具TOP10测评

救命神器&#xff01;专科生必看10款一键生成论文工具TOP10测评 学术写作新选择&#xff1a;2026年专科生论文工具测评指南 在当前高等教育日益普及的背景下&#xff0c;专科生群体在论文写作中面临着时间紧张、资料查找困难、格式不规范等多重挑战。为了帮助大家更高效地完成论…

作者头像 李华
网站建设 2026/6/22 10:14:49

图文详解:Linux epoll和io_uring到底谁更牛?

大家好&#xff0c;这里是物联网心球。一直以来&#xff0c;在Linux高性能网络编程中使用最多的网络I/O模型是epoll。epoll除了性能优越&#xff0c;稳定性也很高&#xff0c;似乎epoll成了高并发应用场景的唯一选择。然而随着io_uring的出现&#xff0c;这一局面慢慢被打破。i…

作者头像 李华
网站建设 2026/6/15 16:21:21

亲测好用9个AI论文平台,助你轻松搞定本科毕业论文!

亲测好用9个AI论文平台&#xff0c;助你轻松搞定本科毕业论文&#xff01; AI 工具如何帮你轻松应对论文写作难题 对于很多本科生来说&#xff0c;写论文不仅是一项学术任务&#xff0c;更是一场心理和时间的双重挑战。从选题、查资料到撰写、修改&#xff0c;每一步都可能让人…

作者头像 李华
网站建设 2026/6/13 17:10:43

springboot毕业设计成绩管理系统的设计与实现(11714)

有需要的同学&#xff0c;源代码和配套文档领取&#xff0c;加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码&#xff08;前后端源代码SQL脚本&#xff09;配套文档&#xff08;LWPPT开题报告&#xff09;远程调试控屏包运行 三、技术介绍 Java…

作者头像 李华
网站建设 2026/6/22 5:28:55

C语言中%d、%f、%p、%c、%s、%的代表意义

在C语言中&#xff0c;printf()&#xff08;以及scanf()等函数&#xff09;使用的 % 字母 称为格式说明符&#xff08;或格式占位符&#xff09;&#xff0c;它们告诉函数应该以什么格式来输出&#xff08;或输入&#xff09;对应的参数。 以下是你问到的几个最常用格式说明符…

作者头像 李华
网站建设 2026/6/22 15:40:22

Excel与SQL数据分析:数据运算全面对比

Excel vs SQL 数据分析&#xff1a;2026年真实场景运算能力全面对比 在2026年的数据分析工作中&#xff0c;Excel 和 SQL 已经不是“你选谁”的问题&#xff0c;而是**“什么时候用哪个 怎么配合”**的问题。 下面用最实用的维度做一次2026年最新认知下的全面对比&#xff0…

作者头像 李华