跳到主内容
快讯直播
AI智模界
AI 词典

CUDA Stream 与异步拷贝:让搬运和计算重叠

一句话定义:CUDA Stream(CUDA 流)是 GPU 上一条按提交顺序执行任务的队列;异步拷贝(asynchronous copy)是把数据搬运任务丢进某条流里排队、调用立刻返回,从而让“搬数据”和“算数据”能同时进行。

为什么需要它:GPU 算得再快,数据得先从主机内存(Host)搬进显存(Device),这一步叫 H2D(Host to Device)。默认情况下,搬运和计算是排队的:搬完才算,算完再搬下一批。于是出现尴尬场面——计算单元满负荷干活时,搬运引擎闲着;搬运时,计算单元干等。

打个比方:一个厨房只有一个灶台(GPU 计算单元)和一个传菜员(拷贝引擎,DMA)。如果每次都要等传菜员把食材从仓库搬到灶台边,灶台就只能熄火等着。聪明的做法是:灶台炒当前这锅时,传菜员已经在把下一批食材搬到备餐台。锅不空,人不停。

流是队列,异步拷贝是快递单。默认流(default stream)像只有一条队伍,所有任务按顺序来。想重叠,就得开多条流:把第 1 批数据的拷贝、内核(kernel)计算、拷回分别提交到流 A,第 2 批提交到流 B,硬件就有机会把搬运和计算真正并排跑起来。异步拷贝的关键是调用后不等结果,只拿到一个“排队号”;真正等待发生在最后的同步调用。

几个容易踩的坑:

  • 只有页锁定内存(pinned memory)才能实现真正的异步传输。普通可分页内存即使调用异步 API,驱动也可能偷偷同步,重叠效果打折。
  • 默认流经常和其它流隐式同步,会把好不容易做出来的重叠抹平。实践中常显式创建流,或按官方文档启用 per-thread 默认流。
  • 流不是越多越好。流太多会争抢搬运引擎和计算资源,反而更慢。
  • 用事件(event)可以精确表达“流 B 等流 A 完成再开始”,别用粗暴的全设备同步。
概念干什么常见误解
同步拷贝调用返回时数据已搬完以为它会自动重叠
异步拷贝 + 流入队后立刻返回以为任何内存都能真异步
默认流隐式串行、隐式同步以为不同流必然并行
显式流 + 事件组织和编排并行任务以为建流不用管开销

对从业者的意义:训练和推理时最常见的性能问题不是算力不够,而是数据供给跟不上——GPU 利用率忽高忽低、时高时低的锯齿曲线,往往就是搬运在挡路。把数据分块做双缓冲(第 k 块在算,第 k+1 块在搬),是几乎所有高性能数据管线的标准做法。

对普通人的意义:这解释了为什么“加一张显卡”不总是线性变快。如果瓶颈在数据从内存搬到显存的速度上,再强的计算单元也只能等着开饭。具体 API 语义和默认流行为以 NVIDIA 官方文档为准。

AI 生成本文由 AI 基于公开信息自动生成,仅供参考。