18 / 24 · 概念
依赖、资源冒险与转发
当操作需要先前结果时,比较停顿和转发。
课时内容可免费阅读,选课后可保存学习进度。
操作重叠不仅需要保持顺序
独立的流式计算不读取先前结果,因此事务可以安全重叠。但使用寄存器堆的运算单元可能需要前一个操作的结果。在较早的写入结果可用之前读取寄存器,会产生写后读数据冒险。算术本身可能正确,但操作数采样过早。
初始 R1=4。I0 执行 R1←R1+3,I1 执行 R2←R1×2。这个示例中,I0 在时钟沿 0 采集操作数 4,在后续周期计算出 7,并在时钟沿 1 写入 R1。I1 若在时钟沿 1 采样 R1,可能看到旧值 4,得到 R2=8。顺序执行要求 R2=14。应明确规定寄存器堆同沿读写的行为。
| 解决方式 | I1 看到的操作数 | 要求 |
|---|---|---|
| 读取旧 R1 | 4 | 此处错误 |
| 停顿到时钟沿 2 | 7 | 保持操作及伴随字段 |
| 转发执行结果 | 时钟沿 1 前的 7 | 结果已可用且路径满足时序 |
转发在计算结果到达体系结构存储之前选择该结果。仅匹配目标寄存器编号并不够:产生结果的操作必须有效、确实写寄存器,且结果已准备好。如果多个产生结果的操作匹配,应选择其中最年轻、但仍早于当前操作的一个。绝不能转发气泡或已被清空的操作。
响应尚未到达的加载操作,不能通过转发不可用数据解决。应让使用该结果的操作停顿,同时保持操作码、源标识和标签。决定其他独立级是否可以继续。
两个级同时需要一个存储器端口时,会产生结构冒险。即使没有数据依赖,也需要仲裁或额外资源。分支引入控制冒险,需要取消错误路径上的工作。分析每个操作等待什么,以及哪些状态必须保持。本课程综合项目仍是独立数据流;通过该项目不能证明 CPU 依赖处理能力。
自己试试
R1=4,I0 加三,I1 将结果加倍。比较 I1 读取旧存储值与正确转发时的结果。如果 I0 是加载操作,且数据尚未可用,应怎样处理?
阅读解释
读取旧值 4 得到 8;转发 7 得到 14。加载结果不可用时,使用方操作必须停顿,并保持操作及标签。目标寄存器匹配不能成为转发未完成数据的依据。