← AMD 专题与八个进阶单元

AMD / LAB 05 OF 08

双缓冲的依赖图:重叠必须服从数据完成

把三批求和组织成两个槽位,证明复用时没有覆盖正在读的数据。

本单元 4 小时。本公司八个单元共 32h,三家公司共额外 96h 核心实践;这笔时间在共同路线之外,未压入厂商入门的44h。

本页是实践讲义。打开、阅读或复制命令不代表完成。新单元的 SDK、simulator 与硬件命令均未在教材建设中执行;自己的结果应按实际后端保存。

先备与马上可用的例子

先完成:amd-04 →

直接打开机制图,边看边手推

PREDICT FIRST

具体问题与独立预期

输入与约定

批次 X0=[3,-1,4,0,2],X1=[1,1,1,1,1],X2=[2,2,2,2,2];两个槽位。教学持续时间 H2D=2、compute=3、D2H=1。

先根据输入写下自己的结果与理由,再展开参考推演;随后运行或检查实现。

对照参考结果与原因

输出 [8,5,10]。每批依赖 H_i→K_i→D_i,批2复用槽0必须等待 D0 完成;持续时间是假设值。

槽位编号 i%2 只选择资源,不是同步机制。不同 stream 中的事件依赖负责约束生产者与消费者。

机制怎样连接起来

先写正确的串行版,再让不同批次进入不同 stream。每个槽位包含自己的 host staging、host output、device input、device output、批号和完成事件。复用前在 host 等待该槽完成,把旧 host output 按旧批号拷入独立 results 数组,再改写 staging 并提交新批;槽号本身不保存所有批次的答案。

用一张 DAG 记录必要依赖,用泳道标资源占用。图上可以看出允许重叠的区间,但实际 GPU 是否重叠取决于 copy engine、页锁定内存、提交节奏和设备资源;这些条件不能由图本身验证。

为缩小工作量,先在一个 stream 内排完一批 H2D、kernel、D2H,在 D2H 后记录完成事件。复用前用 hipEventSynchronize 或等价 host 完成等待来读取旧输出和改写 staging;hipStreamWaitEvent 只给设备排依赖,不能授权 host 立刻覆盖内存。结束时 drain 每个仍有在途批次的槽,将剩余输出存到 results,已经回收的批次不重复保存。

CHOOSE ONE EXECUTION PATH

按手头环境推进

CPU 路径可以先完成。额外的 SDK 或设备验证要有自己的运行记录;本单元的四小时不同时要求完成四个分支。安装等待超过本页预算时,留下阻塞条件,继续可做的数学、代码与协议工作。

CPU · 现有机器 · 本单元尚未验收

条件:现有 macOS 或 Linux;C++20 编译器或 Python 3 标准库。无需加速卡。

本分支做什么:有限调度模型验证先后关系,不测硬件。

保存什么证据:保存自己的源码、输入、实际 stdout/stderr 和退出码;只证明 CPU 逻辑。

教材初始执行状态:not-executed。这不是对你个人学习进度的判断。

SDK · 编译与环境 · 本单元尚未验收

条件:已有兼容 ROCm/HIP 的 Linux 工具链。

本分支做什么:按实际版本核对 hipEventRecord/hipStreamWaitEvent/hipEventSynchronize;编译不等于重叠运行。

保存什么证据:保存实际工具版本与编译命令;仅编译成功不能记成运行通过。

教材初始执行状态:not-executed。这不是对你个人学习进度的判断。

官方 simulator · 本单元尚未验收

条件:只有明确提供并且版本匹配的官方 simulator 才属于此分支。

本分支做什么:本页图和 CPU 调度器不是 HIP simulator。

保存什么证据:记录 simulator 名称、版本、输入、日志、退出状态;网页或 CPU 模型不算 simulator。

教材初始执行状态:not-executed。这不是对你个人学习进度的判断。

真实设备 · 本单元尚未验收

条件:用户已有并可使用的兼容设备或实验室环境;本单元不要求购买、租用或提交集群作业。

本分支做什么:在兼容设备上运行两条 stream,用实际 trace 检查重叠,正确性与性能分开。

保存什么证据:真实设备输出、同步点、设备型号和复现日志单独保存;未执行保持未通过。

教材初始执行状态:not-executed。这不是对你个人学习进度的判断。

READ → BUILD → BREAK → EXPLAIN

四小时,留下一个完整产出

可拆成多个时段。每次停下时保存代码、输入、实际结果和下一步,不用重新读整篇。没有通过当前检查时继续修正,不靠翻页推进。

1. 手推三批 · 30 分钟

  1. 计算三批结果 8/5/10,画槽位 0,1,0 的分配表。
  2. 指出 X2 写入槽0 前需要 D0 完成,而且 host 要先将旧值8保存到 results[0];否则槽0后来只剩10。

这一段的产出:槽位使用表

2. 建立依赖模型 · 40 分钟

  1. 在第34章图中观察 host/device 泳道,再画三批 DAG,增加 D0→host回收batch0→改写槽0→H2 的复用链。
  2. 为每个节点记 earliest_start=max(所有前驱结束,同一资源可用时间),不要把所有设备活动假设为一条资源。

这一段的产出:假设持续时间的模型表

3. 实现流水 · 90 分钟

  1. CPU 路径写有限事件调度器,显式加入D0完成、host回收8到results[0]、staging改写和H2提交四个事件;未回收的输出禁止覆盖。
  2. 有设备时用两组缓冲和两条stream;每槽完成事件在其D2H后记录。若槽仍有旧批次,先在host执行hipEventSynchronize(done[slot]),把该槽host output存入results[old_batch_id],再写新输入、提交新批并更新批号。
  3. 所有host staging在异步上传完成前保持存活;最终drain只等待仍未回收的批次,分别写results[batch_id]。最后检查results完整为[8,5,10],而非只读取两个槽。

这一段的产出:三批结果与依赖图

4. 破坏一条边再修复 · 50 分钟

  1. 仅在CPU模型中跳过旧batch输出回收,尝试直接改写槽0;检查器必须拒绝覆盖尚未存入results[0]的旧结果。补回host完成等待与回收步骤后,三批结果恢复为[8,5,10]。
  2. 测试只有 1 批、2 批和 3 批;验证尾部 drain 后每个结果只回收一次。
  3. 硬件若无法证明 overlap,记录正确性通过和 overlap 未证实两个独立结论。

这一段的产出:复用边回归与 drain 检查

5. 口述性能边界 · 30 分钟

  1. 解释假设 2/3/1 与真实时间的区别。
  2. 提交 DAG、槽位表、三个结果和实际后端状态。

这一段的产出:同步合同

EXPLICIT ENVIRONMENT / EXPLICIT STATUS

命令与可保存的起点

以下代码按各自环境使用,运行前完成对应步骤并核对版本。编译失败后停止,不运行目录中的旧二进制;每次采集日志使用新的运行目录。设备程序仅运行在你已有且可使用的环境中。

这个单元复用前一单元的项目文件,并按上面的具体任务修改。对应章节例子的源码、编译命令和预期输出在本页先备链接里;不要把例子自己的固定成功判定遗留到已改输入的版本中。

一个必须能解释的错误

错误情境:i%2 相同就直接覆盖 host staging。

为什么会错:上一次异步 H2D 可能仍在读取该 host buffer;槽号不提供完成保证。

怎样修复:复用前在host等槽事件完成,先保存旧批号对应输出,再改写staging。设备stream等待不能替代host等待;尾部逐槽drain剩余批次。

EVIDENCE BEFORE ADVANCING

验收与面试追问

  • 独立results保存全部[8,5,10];复用前回收旧输出,末尾drain仅保存剩余批次,每批恰好保存一次。
  • 1/2/3 批测试覆盖启动、复用和收尾。
  • 依赖模型拒绝过早复用;图的时间标注为假设。

最后留下这几项

输入和预期、自己的源码或明确标为推演的状态表、实际命令/输出/退出码、一个失败与修复、后端与版本、尚未执行的部分。运行已有教学例子与独立完成修改分别记录。

1. 两条 stream 能保证并行吗?

对照中文要点与英文回答

它们表达独立序列,硬件资源和依赖决定是否实际重叠。

Two streams express independent sequences. They do not guarantee concurrent execution.

2. 事件放在 kernel 后与 D2H 后有何不同?

对照中文要点与英文回答

前者只能说明 kernel 前序完成,不能证明回读已完成;本槽含 host output 时复用与消费要等 D2H。

An event after the kernel does not cover a later copy-back. My slot completion event is recorded after D2H.

3. 只有一批时还要 drain 吗?

对照中文要点与英文回答

要,最后没有下一次复用来顺便等待;否则函数可能在结果就绪前返回。

The final batch still needs an explicit drain because there is no subsequent slot reuse to wait for it.

这些是依照本单元机制设计的追问,不是公司真题。个人验收仍依据实际代码、测试、测量与口述。

资料与版本核验

  • HIP asynchronous execution ↗

    Streams, events and overlap requirements

    核验日期:2026-09-05。HIP latest / 7.15.0 页面;记录设备 asyncEngineCount 与实际 tracing 工具版本。

  • HIP host memory ↗

    Pinned host memory and host allocation

    核验日期:2026-09-05。HIP latest / 7.15.0 页面;按实际安装版本核对 hipHostMalloc/hipHostFree。

  • HIP error handling ↗

    API return values and asynchronous error reporting

    核验日期:2026-09-05。HIP latest / 7.15.0 页面;保存 hipcc --version 与错误发生的 API 名称。

正文、问题和实践设计依据公开资料独立撰写。官方页面的示例输出是资料中的结果,不是本机运行证据。latest 链接可能变化,请在自己的复现说明中保留实际版本。