专栏导读:为什么需要从 MM 理解 HMM
一个真实的困境假设你是一个 GPU 计算框架的开发者。用户写了这样一段代码float*datamalloc(1GB);// ... 填充数据 ...gpu_kernelgrid,block(data);// 希望 GPU 直接访问 data在传统编程模型下这不可能工作——GPU 有自己的显存VRAMCPU 的malloc返回的指针对 GPU 毫无意义。程序员必须手动管理数据搬移//h:host, d:device. 就是我们常说的 h2d,d2hfloat*h_datamalloc(1GB);// CPU 内存float*d_datagpu_malloc(1GB);// GPU 显存memcpy_to_gpu(d_data,h_data,1GB);// 显式拷贝gpu_kernelgrid,block(d_data);// 用 GPU 指针memcpy_from_gpu(h_data,d_data,1GB);// 拷贝回来这套显式拷贝模型有几个致命问题编程复杂度高— 程序员必须手动管理两套指针和数据一致性无法处理指针追踪— 如果数据结构包含指针链表、树拷贝后指针全部失效过度拷贝— 无法知道 GPU 实际会访问哪些页面只能全量拷贝与系统接口不兼容—fork()、mmap()、信号处理等都可能修改地址空间驱动无从得知理想状态是CPU 和 GPU 共享同一个虚拟地址空间指针在两边通用数据按需自动迁移。这就是 HMM 要解决的问题。什么是 HMMHMMHeterogeneous Memory Management是 Linux 内核内存管理子系统的一组扩展它让设备GPU、FPGA、SmartNIC 等能够镜像进程页表— 设备维护一份与 CPU 一致的地址映射进程用同一个虚拟地址在 CPU 和设备间通信感知页表变化— CPU 侧的munmap、mremap、COW 等操作会自动通知设备更新映射双向迁移页面— 页面可以在 CPU RAM 和设备内存之间按需迁移对应用透明让设备内存参与内核框架— 设备内存拥有struct page可以被内核的迁移、回收等框架管理HMM不是一个独立的子系统而是对现有 MM 机制的一系列精准扩展。它的代码量很小核心仅 ~700 行但它依赖的基础设施横跨整个 MM。为什么必须从 MM 理解 HMM很多开发者试图直接阅读mm/hmm.c然后迅速迷失——因为 HMM 的每一行代码都在调用 MM 的底层接口HMM 做的事依赖的 MM 基础设施遍历进程页表获取物理地址五级页表结构、walk_page_range()框架解码页面在设备内存中非驻留 PTE 编码device private entry保持设备映射与 CPU 一致MMU Notifier 序列号协议迁移页面到设备内存migrate_vma*()三阶段迁移框架让设备内存有 struct pageZONE_DEVICE、dev_pagemap代替设备触发缺页handle_mm_fault()FAULT_FLAG_REMOTE如果你不理解这些基础设施HMM 的代码就是一堆无法解读的函数调用。反过来如果你沿着 MM 的进化脉络学习HMM 的每个设计决策都变得顺理成章。MM 的进化脉络Linux MM 并非一开始就具备管理设备内存的能力。它是随着硬件需求的变化一步步进化而来的注意每一步进化都是在前一步的基础上扩展而非推倒重来mmu_notifier最初是为 KVM 设计的HMM 直接复用它来通知设备migrate_pages()最初是为 NUMA 均衡设计的HMM 扩展出migrate_vma*()支持设备迁移swap entry编码最初只有 swap 和 migration 两种HMM 新增了 device private/exclusive entryHMM 的设计哲学就是复用而非重造。这也是为什么理解 MM 基础是掌握 HMM 的必经之路。硬件背景谁在用 HMMGPU主要消费者厂商驱动HMM 使用方式AMDamdgpu / KFDhmm_range_fault()migrate_vma*()实现 SVMROCmIntelXe通过drm_gpusvm框架使用 HMMNVIDIANouveau开源nouveau_svm使用 HMM 做 SVMCXL 设备CXLCompute Express Link设备提供 CPU 可直接访问的扩展内存。内核用DEVICE_COHERENT类型的 ZONE_DEVICE 管理未来可能成为 HMM 最大的应用场景。其他FPGA— 可通过 HMM 共享进程地址空间SmartNIC / DPU— RDMA 设备内存管理持久化内存PMEM— 虽然不用 HMM但共享 ZONE_DEVICE 基础设施本专栏的学习路径我们把 HMM 的知识体系分为8 层沿进化脉络从底向上每一层我们都会讲清经典 MM 是怎么做的— 建立基础心智模型指出不够在哪里— 面对设备内存时的局限展示如何扩展— 内核社区的解决方案这样当你最终读到mm/hmm.c时每一行代码都不再陌生。前置知识本专栏假设你具备C 语言基础— 能读懂内核代码指针、位操作、宏操作系统概念— 虚拟内存、页表、中断等基本概念基本的内核阅读能力— 知道如何浏览内核源码树不需要你已经精通 MM 或 GPU 驱动——这些正是本专栏要教的。关键源码版本本专栏基于Linux 6.x内核源码。HMM 相关代码在近几年持续演进核心文件包括文件内容mm/hmm.cHMM 核心实现~700 行include/linux/hmm.hHMM 公共 APImm/migrate_device.c设备迁移框架mm/memremap.cZONE_DEVICE 实现lib/test_hmm.cHMM 测试模块最佳学习参考下篇预告第 1 篇虚拟地址空间与页表——每个进程的私有世界我们将从 MM 最基础的概念开始进程如何拥有自己的虚拟地址空间页表如何将虚拟地址翻译为物理地址五级页表的结构是什么样的这些看似老生常谈的基础恰恰是 HMMhmm_range_fault()遍历页表时的核心路径。打好这个基础后面的一切才能事半功倍。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2633733.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!