一句话定义:锁页内存(Pinned Memory,也叫页锁定内存 page-locked memory)是被操作系统"钉"在物理内存里、不允许被换出到磁盘的那部分主机内存;H2D 拷贝(Host-to-Device Copy)就是把数据从主机内存送进 GPU 显存的动作。这两件事凑在一起,往往决定了 GPU 到底能多快"吃上饭"。
为什么这一步容易成为瓶颈
GPU 算得很快,但它的数据大多先在主机内存里准备好。搬运由 DMA 引擎完成,它只认物理地址、不会"进屋"取货。问题在于,普通的主机内存是"可分页内存"(pageable memory):操作系统随时可以把它换到磁盘(swap),也可以为了整理内存碎片把它在物理内存里挪个位置。地址会变,DMA 就不敢直接读。
于是驱动采取折中方案:临时申请一小块锁页缓冲,先把数据从可分页内存拷进这块缓冲,再从缓冲 DMA 到显存——搬两趟。
打个比方:你要把客厅里的箱子装车。货车司机不进楼,只在楼下装货;而箱子随时可能被房东挪走甚至搬去仓库。所以你得先把箱子搬到楼下临时堆放点,再装车。如果箱子本来就放在楼下固定的位置(锁页内存),司机来了直接装车,一趟搞定。
所以锁页内存"锁"的是物理页:既不许换出到磁盘,也不许操作系统在物理内存中移动它。物理地址固定,DMA 就能拿着地址直接读写。
和相邻概念的区别
锁页内存不是"更快的内存",也不是缓存(cache),它只是内存的一种属性;它和显存、统一内存(Unified Memory)也不是一回事。真正的收益是:省掉一次中转拷贝,并且让异步拷贝成为可能——拷贝与计算可以重叠进行,而走可分页内存的传输通常是同步阻塞的。
| 可分页内存 Pageable | 锁页内存 Pinned | |
|---|---|---|
| 能否被换出到磁盘 | 能 | 不能 |
| 物理地址是否固定 | 否 | 是 |
| H2D 路径 | 经临时锁页缓冲中转,两次拷贝 | DMA 直传,一次拷贝 |
| 能否异步、与计算重叠 | 一般不能 | 可以 |
| 分配/释放开销 | 低 | 较高,且占用不可回收的物理内存 |
对从业者的实际意义
训练框架的数据加载器常见 pin_memory=True,就是把一个 batch 放进锁页内存,再配合非阻塞传输,让"搬下一个 batch"和"算当前 batch"重叠;推理服务里做流式大文件传输时,通常只用几块锁页缓冲做双缓冲循环复用,而不是把整份数据都 pin 住。反过来,锁页内存是稀缺资源:分配慢、用量大时会挤占整机内存,用完要及时释放,多进程场景下每个进程 pin 的份额还会累加。
一句话记住:锁页内存不提高带宽上限,它省的是中转和等待;H2D 慢,往往慢在这两件事上。具体 API 行为以官方文档为准。
