集成 GPU 统一内存:独显 HBM 之外,UMA 如何省掉 PCIe 拷贝
更新时间:2026-09-25。前面几篇讲 GPU,默认对象都是插在 PCIe 插槽上的独立显卡:它有自己的 HBM 显存,GPU 内存层级里那条 2~3.35 TB/s 的带宽就是从这里来的。但日常更多的 GPU——笔记本核显、手机、游戏主机、Apple Silicon 的 Mac——根本没有「显存」这个独立部件。本篇讲清这条路线:集成 GPU 与 CPU 共用同一批内存字节(UMA,Unified Memory Architecture,统一内存架构),省掉拷贝,代价是带宽和容量都要和 CPU 分。
本文要回答的问题
- 独显和集显在物理上各自怎么接内存,数据路径差在哪?
- 为什么说统一内存是 zero-copy、一个指针 CPU 和 GPU 两边通用?
- 省掉 PCIe 拷贝的同时,集显付出了哪些代价,带宽和功耗差多少?
- Apple Silicon、手机 SoC、新 x86 核显分别把 UMA 做成了什么样?
- 统一内存对编程模型意味着什么,page migration 和 over-subscription 该怎么直觉理解?
一、两种放置 GPU 的方式:分家用还是合伙用
先把两种架构画在一张图上。独显模型里,CPU 和 GPU 是两颗独立芯片,各自挂自己的内存:CPU 侧是 DDR5 内存条,GPU 侧是封装内的 HBM 或板载 GDDR6X,两者之间唯一的通道是 PCIe。集显模型(AMD 称 APU,手机和 Mac 称 SoC)里,CPU 核心和 GPU 核心在同一颗芯片(或同一封装)上,通过片上互联共享同一批内存控制器和同一批 DRAM 颗粒。
这张对比图是全篇的骨架。两种方案的差异不在 GPU 核心本身——SIMT、warp 调度那套机制两边一样(见 GPU 架构:warp 调度器)——差异全在数据离 GPU 有多远、归谁所有。独显给 GPU 配了一栋独门独户的高速仓库,但 CPU 的货要送进去必须走 PCIe 这条窄桥;集显让两边合伙用同一个仓库,谁都能直接伸手,但仓库本身的门没那么宽。
值得补一句历史:集显并不是新发明,早在二十年前南北桥时代就有把图形核心并入芯片组、共享系统内存的做法,当年以「慢」出名,瓶颈正是单通道内存和孱弱的片上互联。UMA 今天能翻身,靠的是三件事一起成熟:LPDDR5X 把移动内存带宽推到百 GB/s 级、片上网络和大容量末级缓存能承接住混合流量、以及 GPU 的主战场从「重度渲染」扩展到了流式图形和端侧推理。所以理解 UMA 不能只看某一代产品的跑分,它是一整条系统路线演进的结果。
二、独显的数据路径:拷贝不是免费的
在独显上写 CUDA,经典流程是三段式:在主机内存准备数据,cudaMemcpy 经 PCIe 拷到显存,GPU 算完再拷回来。即使有 CUDA Unified Memory 帮你按需迁移页面,物理通道仍是这条 PCIe。
问题在于桥宽和仓库门宽差了一个数量级还多。PCIe 5.0 x16 单向带宽约 64 GB/s,而 H100 的 HBM 带宽约 3.35 TB/s——显存吃数据的速度是 PCIe 喂料速度的五十倍。PCIe 4.0 x16 约 32 GB/s,比值更是百倍。这带来两个直接后果。
其一,拷贝要占真实时间。搬运 1 GB 数据,PCIe 4.0 理论下限就要约 30 ms,而 H100 在这 1 GB 上做一次典型推理也许只要几毫秒;如果每次计算都重新搬,性能完全被桥锁死。成熟的做法是数据一次搬入、在显存里驻留反复算,所以大模型服务才强调 KV cache 和权重常驻。其二,拷贝期间两端资源都被占用:GPU 在等数据到齐,CPU 侧要先在可 DMA 的锁页内存(pinned memory)里备齐数据,普通可分页内存还要先走一次内部中转;小批量、高频次的传输会被每次几微秒到十几微秒的命令提交开销和同步栅栏放大,实测带宽常只有理论峰值的一半到八成。其三,拷贝还占功耗:位翻转和 IO 驱动是实打实的能量支出,在移动端每多搬一兆字节都要从电池预算里扣,这也是后面 UMA 路线在手机上胜出的物理原因之一。
也就是说,独显的高显存带宽有个前提:数据得已经在显存里。这个前提在数据中心的批量推理、训练里成立(数据反复用、搬一次摊薄到无数次计算),在「CPU 刚产出一帧数据、GPU 只处理一下就显示」的图形和轻量负载里却很别扭——而后者恰恰是手机和轻薄本的主要场景。
三、UMA 的收益:zero-copy 与一个指针两边通用
集显把仓库合并之后,PCIe 这整段路径从物理上消失了。CPU 写出的数据落在共享内存里,GPU 直接拿同一个虚拟地址去读,不需要任何拷贝——这就是 zero-copy(零拷贝)。更准确地说,两边的页表指向同一批物理页,驱动通过 IOMMU/SMMU 之类的地址转换单元让 GPU 也能安全寻址主内存:设备侧看到的地址经转换后落在真实物理页上,越界访问被硬件拦掉,操作系统因此敢把 GPU 当成一个普通的内存访问者放进进程地址空间。
可以拿一个具体场景体会差别。独显上做视频处理,解码后的帧先到主机内存,要再经一次 PCIe 上传才能做图像增强,增强完又要取回给编码器,一帧数据在路上出现三份拷贝;UMA 上解码器、GPU 增强核、编码器全在一颗 SoC 里,帧缓冲始终只有一份,三个单元排着队在同一批物理页上接力。手机能在 5 W 左右的功耗预算内完成 4K 视频实时处理与回放,这种「数据不动、处理单元轮流上门」的系统结构和 GPU 计算核心本身同等重要,二者缺一不可。
这改变了编程时最基本的心智模型。独显上指针是「分国籍」的:主机指针在 GPU 上解引用是非法地址,必须先 cudaMemcpy 换出一个设备指针。UMA 上只有一个地址空间,CPU 代码拿到的指针原样传给 GPU kernel,规则、对齐、生命周期全都统一。Metal 在 Apple Silicon 上的 MTLBuffer、Linux 上基于 HMM(Heterogeneous Memory Management)的 OpenCL/CUDA、安卓的 AHardwareBuffer,底层都是这件事。
收益分三层看。第一层是省掉拷贝的字节数和时间,图形场景尤其明显:合成桌面、渲染网页时,纹理和帧缓冲本就由 CPU 侧的各类解码器和 UI 进程产生,zero-copy 让这些数据直接进入 GPU 管线。第二层是省掉双份内存占用,同一份数据不必在主机和设备各存一份,对内存本就以 GB 计的移动设备是实打实的空间节省。第三层是编程简化:少一类 bug(忘记拷贝、拷贝方向写反、释放后还在另一端使用),CPU 与 GPU 的细粒度交错计算(CPU 改一点、GPU 算一点、来回很多轮)终于不再被拷贝税惩罚。
这里要澄清一个常见误解:zero-copy 省的是内存到内存的复制,不省缓存同步。CPU 和 GPU 各有自己的 cache 层级,一方写完之后,另一方读到的是否是最新值,仍要靠一致性协议或显式栅栏保证。高端 SoC(Apple Silicon、新游戏主机、部分 x86 APU)在片上互联里实现了 CPU 与 GPU 之间的缓存一致性,共享页在两边 cache 间按硬件协议失效与回填;成本更低的移动设计则只做到内存级一致,程序仍需在生产者写完、消费者读之前插入内存屏障或调用框架提供的同步接口。把「指针通用」误当成「时序随便写」,是 UMA 上最隐蔽的一类数据竞争来源。
四、代价:共享带宽、吃系统内存,以及典型数字
合伙用仓库的代价同样直接。先看数量级对比(数值为 2025~2026 年代表产品的典型规格,随代际变化,量级关系稳定):
| 对比维度 | 独立显卡 | 集成 GPU / SoC(UMA) |
|---|---|---|
| GPU 专用内存 | 独立 HBM 或 GDDR6X,GPU 独占 | 无独立显存,与 CPU 共用 LPDDR5X/DDR5 |
| GPU 可用带宽 | H100 约 3.35 TB/s;RTX 4090 约 1.0 TB/s | Apple M4 约 120 GB/s;DDR5-5600 双通道约 90 GB/s;游戏主机约 448 GB/s;M2 Ultra 靠八通道做到约 800 GB/s |
| CPU↔GPU 数据路径 | 经 PCIe 5.0 x16 约 64 GB/s,显式拷贝 | 片上互联,zero-copy,无独立通道 |
| 典型功耗 | 整卡 350~700 W(H100 SXM 700 W,4090 约 450 W) | 整个 SoC 封装 15~65 W;手机 SoC 持续约 5~10 W |
| 内存容量 | 显存 24~192 GB 独占 | 共享系统内存 16~256 GB,GPU 占用直接挤压应用可用内存 |
| 擅长场景 | 训练、批量推理、重度渲染:数据常驻、算力碾压 | 日常图形、轻量推理、移动端:数据流式产生、省拷贝省功耗 |
三个代价值得展开。带宽天花板低:主流集显的百 GB/s 级带宽喂不饱为 TB/s 设计的 GPU 核心,所以集显的计算单元规模本身就要按带宽裁剪,核显打独显从来不是靠核心数。同样跑一个吃带宽的 kernel,独显是「核心被带宽轻微限制」,集显则是「核心数砍到只配吃这点带宽」,这解释了为什么核显规格表上的流处理器数量通常只有同代独显的十几分之一。争抢:CPU 和 GPU 同时吃内存控制器时互相抢带宽,游戏里帧率波动、后台编译时画面卡顿,很多都来自这里;实测中 GPU 满载时,CPU 侧的内存拷贝带宽可以跌掉三分之一以上。厂商的对策是在 QoS 逻辑里给实时图形流量划优先级、在封装里放大 LLC(末级缓存)做缓冲——共享 LLC 还顺带让 CPU 刚写入的数据在 GPU 读取时有机会直接命中片上缓存,这是独显学不到的红利。吃系统内存:BIOS/系统里给核显划的「显存」(常见 2~8 GB)是从物理内存里扣的,应用申请缓冲也是真金白银占用统一内存,8 GB 内存的机器开个集显游戏立刻捉襟见肘。显存技术细节(HBM 为何贵、GDDR 与 LPDDR 的取舍)见 GPU 显存 HBM 与 GDDR。
五、三条现实路线:Apple Silicon、手机 SoC、新 x86 核显
**Apple Silicon 是最彻底的 UMA。**从 M1 起,CPU、GPU、神经网络引擎、媒体编解码器全部挂在共享的统一内存上,M1 带宽约 68 GB/s,M3/M4 约 120 GB/s,M2 Ultra 用八通道 LPDDR5 堆到约 800 GB/s——后者正是为了让 Ultra 级别的 GPU 算力有饭吃。整个 Mac 产品线不插一根显存,封装内的内存容量(最高 256 GB)对所有处理单元一视同仁。这让 Mac 成了大模型本地部署的意外赢家:无需经过 PCIe 搬运,CPU 刚加载的权重 GPU 直接可用。注意 Apple 对「统一内存」这个词的用法和通用 UMA 略有差别——它特指所有处理单元共享同一个物理内存池、且媒体引擎和 GPU 还能直接共享未压缩缓冲,连传统显卡里 CPU 到 GPU 的纹理上传路径都省了。
**手机 SoC 是 UMA 的原生场景。**功耗预算只有 5~10 W,物理上不可能容纳独显级显存子系统;高通、天玑、苹果 A 系列都是 CPU/GPU/ISP/视频单元共享 LPDDR5X。手机的图形负载天然是流式的(相机帧 → GPU 合成 → 显示),zero-copy 省下的不仅是时间,更是搬运本身要烧的电。游戏主机走的也是同一路线:PS5、Xbox 把 GPU 和 CPU 做进一颗 APU,配 256~512 bit 宽总线上的高速 GDDR6,拿到约 448~560 GB/s 的共享带宽——介于集显和独显之间。
**x86 核显正在补课。**AMD 的 APU 路线(Ryzen 8000G、Ryzen AI 300)配 LPDDR5X-7500 时带宽约 120 GB/s,并率先在 x86 上支持统一内存编程;Intel 从 Meteor Lake 起把核显、NPU 都放进 chiplet 封装,搭配 LPDDR5X 并支持 ATS(Address Translation Services,地址转换服务),让设备能直接访问进程虚拟地址。x86 阵营还有一个特殊的中间形态:带少量板载高速缓存的独显级 iGPU(如部分 Max+ 设计),用一小块 SRAM/HBM 给共享带宽补短板,本质是「UMA 为主、加一块缓冲」。
这里有个容易踩的选型坑:同一颗 APU 插 DDR5 台式内存和焊 LPDDR5X,集显性能可能差出三到五成——差别不在 GPU 而在内存:LPDDR 颗粒通常以更宽的总线、更高的有效频率直连封装,而台式机双通道 DDR5 还可能被用户只插一根内存条降级成单通道,带宽直接腰斩。所以看集显评测,第一条要问的永远是「配的什么内存、几通道」,而不是 GPU 核心频率。
六、对编程模型的影响:page migration 与 over-subscription
统一内存不等于「想怎么用就怎么用」,两个机制必须建立直觉。
**page migration(页面迁移)**解决「数据现在离谁近」的问题。即使地址空间统一,物理页的位置仍影响速度:独显 + Unified Memory 上,页面在首次被 GPU 触碰时从主机内存迁到显存,迁回时反向;HMM/ATS 让这套迁移由缺页驱动、对源码透明。SoC 上两边到 DRAM 的物理路径一致,迁移问题弱化为缓存放置问题。两种用法的对比可以画成下图。
写代码的直觉是:指针统一消除的是拷贝代码,不消除数据物理流动的成本。一个页面在 CPU 和 GPU 间被反复交替写,会触发乒乓迁移,每次缺页都要排队等迁移完成,性能比显式批量拷贝还差;好的模式仍是让一批数据在一段时间内主要归一边用,和独显上的数据驻留原则一脉相承。API 层面也预留了手动接口:CUDA 的 cudaMemPrefetchAsync 可以提前把整段地址预取到指定设备,把缺页迁移从「计算中途一个一个发生」改成「开工前一次性批量完成」,这类提示在 UMA 编程里和独显上同样值得用。
**over-subscription(超分)**解决「数据比内存大」的问题。统一地址空间允许分配超过物理内存的缓冲:系统把冷页面换出到压缩内存或存储(Mac 的 swap、Linux 的 zram/swap),需要时再换入。独显上 CUDA Unified Memory 也允许显存超分,多余页面退回主机内存。直觉上它让程序「能跑」,但跑和跑得快是两回事:GPU 工作集超出物理内存后,缺页和换页走的是慢通道(百 GB/s 甚至仅数 GB/s 的存储带宽),相对 HBM 是几百倍的降速,性能曲线往往是阶梯式崩掉的——前一秒还接近满速,工作集一越过物理内存边界,帧率或吞吐直接掉到零头。更麻烦的是 GPU 缺页往往以数千线程并发的方式到来,换页通道瞬间被打满,恢复也比 CPU 程序慢。所以统一内存编程仍要算工作集:可以超分来保证功能正确、跑完偶发的大批量任务,但热数据必须压在物理内存容量之内,这与独显时代「模型必须塞进显存」的约束只是换了个说法。一个实用的自查动作是运行时观察驻留页与换页计数(Mac 的内存压力、Linux 的 vmstat 及驱动计数器),看到持续换页就该减批量,而不是再加优化指令。
这一篇在知识体系里的位置
本篇是 GPU 硬件与编程模型系列的横向对照篇:上承 GPU 架构:warp 调度器(GPU 核心怎么算)和 GPU 内存层级(片上四层金字塔),把视角从「独显内部」拉到「GPU 在系统里怎么放」。往软件走,页面按需迁移的细节读 CUDA Unified Memory;往器件走,HBM、GDDR、LPDDR 的技术取舍读 GPU 显存 HBM 与 GDDR;往 CPU 侧的地址转换走,可对照 MMU/TLB 虚拟内存,warp 分支行为的细节见 SIMT 与分支发散。
总结
集成 GPU 统一内存(UMA)把 GPU 和 CPU 接在同一批物理内存上:独显是「CPU+DDR ←PCIe 5.0 约 64GB/s 拷贝→ GPU+HBM 2~3.35TB/s」,集显/APU/SoC 则是两边经片上互联共享 LPDDR5X/DDR5(典型 90~120GB/s,游戏主机约 448GB/s,M2 Ultra 约 800GB/s),换来 zero-copy、指针两边通用、不存双份数据和整个 SoC 仅 15~65W 的低功耗,代价是带宽低一两个数量级、与 CPU 互相争抢、GPU 缓冲直接吃系统内存;Apple Silicon、手机 SoC、Ryzen AI 与 Meteor Lake 是三条已经落地的路线;对程序员而言,统一地址空间消灭的是拷贝代码而不是数据流动成本——page migration 乒乓和 over-subscription 换页仍是真实的性能悬崖,正确直觉是让数据一段时间内主要归一边用、热工作集始终压在物理内存之内。